In [ ]:
import pandas as pd
import numpy as np

# Carregar o arquivo Excel
xls = pd.ExcelFile('Exercicio_Python_CRM .xlsx')

# Obter os nomes das abas
sheet_names = xls.sheet_names

# Para cada aba, ler o schema e as primeiras 10 linhas
for sheet in sheet_names:
    df = pd.read_excel(xls, sheet_name=sheet, nrows=10)
    print(f"Schema para {sheet}:")
    print(df.dtypes)
    print(f"Primeiras 10 linhas para {sheet}:")
    print(df.head(10))
Schema para Instruções:
Unnamed: 0    float64
Unnamed: 1     object
dtype: object
Primeiras 10 linhas para Instruções:
   Unnamed: 0                                         Unnamed: 1
0         NaN                    Teste de Seleção - Python CRM 2
1         NaN                                                NaN
2         NaN  Neste arquivo você econtra dados hipotéticos d...
3         NaN                                                NaN
4         NaN                                        Instruções:
5         NaN                                                NaN
6         NaN  Utilizando Pandas e Numpy (ou se preferir, out...
7         NaN                                                NaN
8         NaN  0. Importar os dados das abas em cor verde do ...
9         NaN                                                NaN
Schema para Transações:
ID_Trans                     int64
Data                datetime64[ns]
ID_Loja                      int64
ID_Produto                   int64
ID_Cliente                   int64
UnidadesVendidas             int64
ValorTotal                 float64
Promo                      float64
dtype: object
Primeiras 10 linhas para Transações:
   ID_Trans       Data  ID_Loja  ID_Produto  ID_Cliente  UnidadesVendidas  \
0         1 2022-01-01        7      123005       90023                 2   
1         2 2022-01-01        9      123004       90092                 1   
2         3 2022-01-01        1      123001       90027                 2   
3         4 2022-01-01        3      123001       90097                 2   
4         5 2022-01-01        4      123004       90089                 2   
5         6 2022-01-02        4      123006       90021                 3   
6         7 2022-01-02        9      123005       90072                 4   
7         8 2022-01-02        1      123002       90006                 3   
8         9 2022-01-03        6      123002       90006                 2   
9        10 2022-01-03        3      123002       90069                 1   

   ValorTotal  Promo  
0      99.980    0.0  
1      35.990    0.0  
2      51.980    0.0  
3      51.980    0.0  
4      71.980    0.0  
5     151.173    1.0  
6     199.960    0.0  
7      83.970    0.0  
8      55.980    0.0  
9      25.191    NaN  
Schema para Produto:
ID_Produto            int64
Descrição Produto    object
Categoria            object
Cor                  object
Marca                object
dtype: object
Primeiras 10 linhas para Produto:
   ID_Produto         Descrição Produto Categoria       Cor   Marca
0      123000   Bottom Azul Marca AlfaX    Bottom      Azul   AlfaX
1      123001    Top Cinza Marca GammaZ       Top     Cinza  GammaZ
2      123002  Bottom Preto Marca BetaY    Bottom     Preto   BetaY
3      123003           Top Marca BetaY       Top  Vermelho   BetaY
4      123004     Top Cinza Marca BetaY       Top     Cinza   BetaY
5      123005     Top Cinza Marca AlfaX       Top     Cinza   AlfaX
6      123006  Bottom Preto Marca AlfaX    Bottom     Preto   AlfaX
7      123007           Top Marca AlfaX       Top  Vermelho   AlfaX
8      123008          Top Marca GammaZ       Top  Vermelho  GammaZ
9      123009          Top Marca GammaZ       Top  Vermelho  GammaZ
Schema para Lojas:
ID_Loja     int64
UF         object
Regiao     object
dtype: object
Primeiras 10 linhas para Lojas:
   ID_Loja     UF        Regiao
0        1     AM         NORTE
1        2     MG  CENTRO-OESTE
2        3     SP       SUDESTE
3        4     SP           NaN
4        5    SP        SUDESTE
5        6     SP       SUDESTE
6        7     RS           SUL
7        8     RS           SUL
8        9     BH      NORDESTE
9       10     BH           NaN
Schema para Cliente:
CustomerID       int64
Genero          object
FaixaIdade      object
ClasseSocial    object
dtype: object
Primeiras 10 linhas para Cliente:
   CustomerID     Genero FaixaIdade ClasseSocial
0       90000   Feminino      35-45            C
1       90001   Feminino        45+            D
2       90002   Feminino      18-25            C
3       90003   Feminino        45+            C
4       90004   Feminino      35-45            C
5       90005   Feminino      25-35            D
6       90006  Masculino      18-25            E
7       90007  Masculino      25-35            C
8       90008   Feminino      25-35            E
9       90009   Feminino      18-25            C
Schema para Teste:
CustomerID     int64
Grupo         object
Enviado        int64
Recebido       int64
Aberto         int64
Sessao         int64
Comprou        int64
dtype: object
Primeiras 10 linhas para Teste:
   CustomerID     Grupo  Enviado  Recebido  Aberto  Sessao  Comprou
0       90000     TESTE        1         1       1       1        1
1       90001     TESTE        1         1       0       0        0
2       90002  CONTROLE        1         1       0       0        0
3       90003     TESTE        1         1       1       1        1
4       90004     TESTE        1         1       1       1        1
5       90005     TESTE        1         1       1       1        0
6       90006     TESTE        1         1       0       0        0
7       90007  CONTROLE        1         1       1       1        1
8       90008     TESTE        1         1       1       1        1
9       90009     TESTE        1         1       1       1        1
In [ ]:
import openpyxl

# arquivo
wb = openpyxl.load_workbook('Exercicio_Python_CRM .xlsx', read_only=True)

# aba de transações
ws = wb['Transações']

# tamanho do chunk para leitura de bases grandes
chunk_size = 100000
chunks = []

# cabeçalho (nomes das colunas) da primeira linha
header = [cell.value for cell in ws[1]]

# dados em chunks para bases com milhões de linhas
for i in range(2, ws.max_row, chunk_size):  # Comecça de 2 porque a primeira linha é o cabeçalho
    rows = ws[i:i + chunk_size]
    data = [[cell.value for cell in row] for row in rows]
    df = pd.DataFrame(data, columns=header)  # Usando o cabeçalho como nomes das colunas
    chunks.append(df)

# Concatenando os chunks em um único DataFrame
df_t = pd.concat(chunks, axis=0)

# Para cada coluna no DataFrame
for col in df_t.columns:
    # Se o tipo de dados da coluna é object (string)
    if df_t[col].dtype == 'object':
        # Remova os espaços em branco no início e no final
        df_t[col] = df_t[col].str.strip()
In [ ]:
df_t.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7791 entries, 0 to 7790
Data columns (total 8 columns):
 #   Column            Non-Null Count  Dtype         
---  ------            --------------  -----         
 0   ID_Trans          7791 non-null   int64         
 1   Data              7791 non-null   datetime64[ns]
 2   ID_Loja           7791 non-null   int64         
 3   ID_Produto        7791 non-null   int64         
 4   ID_Cliente        7791 non-null   int64         
 5   UnidadesVendidas  7791 non-null   int64         
 6   ValorTotal        7791 non-null   float64       
 7   Promo             7775 non-null   float64       
dtypes: datetime64[ns](1), float64(2), int64(5)
memory usage: 487.1 KB
In [ ]:
df_t['Promo'] = df_t['Promo'].astype(str)
In [ ]:
df_t.head()
Out[ ]:
ID_Trans Data ID_Loja ID_Produto ID_Cliente UnidadesVendidas ValorTotal Promo
0 1 2022-01-01 7 123005 90023 2 99.98 0.0
1 2 2022-01-01 9 123004 90092 1 35.99 0.0
2 3 2022-01-01 1 123001 90027 2 51.98 0.0
3 4 2022-01-01 3 123001 90097 2 51.98 0.0
4 5 2022-01-01 4 123004 90089 2 71.98 0.0
In [ ]:
df_t['Data'].min(), df_t['Data'].max()
Out[ ]:
(Timestamp('2022-01-01 00:00:00'), Timestamp('2023-09-30 00:00:00'))
In [ ]:
# Filtrando colunas que não contêm 'ID' no nome
cols = [col for col in df_t.columns if 'ID' not in col]

# Descrevendo apenas essas colunas
df_t[cols].describe()
Out[ ]:
UnidadesVendidas ValorTotal
count 7791.000000 7791.000000
mean 2.302657 114.133276
std 0.892296 72.627427
min 1.000000 16.990000
25% 2.000000 55.990000
50% 2.000000 89.990000
75% 3.000000 161.973000
max 4.000000 367.960000
In [ ]:
# verificando valores nulos
null_counts = df_t.isnull().sum()
print(null_counts)
ID_Trans            0
Data                0
ID_Loja             0
ID_Produto          0
ID_Cliente          0
UnidadesVendidas    0
ValorTotal          0
Promo               0
dtype: int64
In [ ]:
# verificando valores duplicados

for column in df_t.columns:
    print(f"\nColumn: {column}")
    print(df_t[column].value_counts(dropna=False))
Column: ID_Trans
1       1
5175    1
5203    1
5202    1
5201    1
       ..
2593    1
2592    1
2591    1
2590    1
7791    1
Name: ID_Trans, Length: 7791, dtype: int64

Column: Data
2022-03-17    88
2022-04-27    84
2022-05-14    82
2023-03-11    77
2022-03-09    75
              ..
2022-07-14     1
2022-07-13     1
2023-08-02     1
2023-06-11     1
2022-05-23     1
Name: Data, Length: 546, dtype: int64

Column: ID_Loja
3     927
9     903
2     884
4     862
7     853
6     842
8     837
5     813
10    437
1     433
Name: ID_Loja, dtype: int64

Column: ID_Produto
123004    850
123005    842
123003    828
123002    824
123008    822
123006    806
123007    795
123001    639
123009    592
123010    380
123000    228
123011    185
Name: ID_Produto, dtype: int64

Column: ID_Cliente
90016    100
90096     99
90083     99
90011     98
90089     96
        ... 
90042     58
90010     57
90020     50
90000     39
90099     32
Name: ID_Cliente, Length: 100, dtype: int64

Column: UnidadesVendidas
2    2882
3    2630
1    1610
4     669
Name: UnidadesVendidas, dtype: int64

Column: ValorTotal
55.980     403
179.980    384
83.970     374
269.970    360
71.980     266
          ... 
105.366      1
21.250       1
107.982      1
125.990      1
26.990       1
Name: ValorTotal, Length: 170, dtype: int64

Column: Promo
0.0    7198
1.0     577
nan      16
Name: Promo, dtype: int64
Primeira parte da análise:¶
  • análise descritiva da base de Transações
  • agregação Ano e Mês
  • KPI Ticket Médio
nesta primeira parte da análise é possível verificar que:¶
  • a base apenas possui dados para 01-2022 até 09-2022 e depois 01-2023 até 09-2023 faltando o último trimestre dos dois anos; época de Natal!
  • as vendas de 2023 apenas se recuperaram no terceiro trimestre
  • o ano de 2023 teve menos promoções e menos Unidades vendidas em relação a 2022, porém obteve um Valor Total maior indicando que houve um Ticket Médio maior em 2023 em relação a 2022
  • o Ticket Médio de 2023 foi sempre maior que 2022 no agregado mês a mês
In [ ]:
import plotly.graph_objects as go

# Agrupando os dados por data
grouped = df_t.groupby('Data').sum()

# Criando o gráfico de barras para 'ValorTotal'
bar1 = go.Bar(x=grouped.index, y=grouped['ValorTotal'], name='ValorTotal')

# Criando outro gráfico de barras para 'UnidadesVendidas'
bar2 = go.Bar(x=grouped.index, y=grouped['UnidadesVendidas'], name='UnidadesVendidas', yaxis='y2')

# Criando a figura e adicionando os gráficos
fig = go.Figure(data=[bar1, bar2])

# Configurando os eixos
fig.update_layout(
    yaxis=dict(title='ValorTotal'),
    yaxis2=dict(title='UnidadesVendidas', overlaying='y', side='right')
)

fig.show()
In [ ]:
import seaborn as sns

# Data to datetime
df_t['Data'] = pd.to_datetime(df_t['Data'])

# Criando colunas para o mês e o ano
df_t['Year'] = df_t['Data'].dt.year
df_t['Month'] = df_t['Data'].dt.month

# Agrupando os dados por ano e mês
grouped = df_t.groupby(['Year', 'Month']).sum().reset_index()

# Obtendo as cores da paleta "Pastel2"
colors = sns.color_palette("Pastel2", len(grouped['Year'].unique())).as_hex()

# Criando o gráfico de barras para 'ValorTotal'
fig = go.Figure()

for i, year in enumerate(grouped['Year'].unique()):
    fig.add_trace(go.Bar(x=grouped[grouped['Year'] == year]['Month'], 
                         y=grouped[grouped['Year'] == year]['ValorTotal'], 
                         name=str(year),
                         marker_color=colors[i]))  # Aplicando as cores

# Configurando os eixos
fig.update_layout(
    xaxis=dict(title='Month'),
    yaxis=dict(title='ValorTotal'),
)

fig.show()
In [ ]:
# Definindo a paleta de cores Pastel2
pastel2 = ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc']

# Criando colunas para o mês e o ano
df_t['Year'] = df_t['Data'].dt.year
df_t['Month'] = df_t['Data'].dt.month

# Agrupando os dados por ano e mês
grouped = df_t.groupby(['Year', 'Month']).sum().reset_index()

# Criando a figura
fig = go.Figure()

# Adicionando o gráfico de barras para 'ValorTotal'
for i, year in enumerate(grouped['Year'].unique()):
    fig.add_trace(go.Bar(x=grouped[grouped['Year'] == year]['Month'], 
                         y=grouped[grouped['Year'] == year]['ValorTotal'], 
                         name='ValorTotal ' + str(year),
                         marker_color=pastel2[i % len(pastel2)]))  # Use a cor correspondente da paleta

# Adicionando o gráfico de linha para 'UnidadesVendidas'
for i, year in enumerate(grouped['Year'].unique()):
    line_color = '#0000ff' if year == 2023 else pastel2[(i + len(pastel2) // 2) % len(pastel2)]  # Use blue color for 2023
    fig.add_trace(go.Scatter(x=grouped[grouped['Year'] == year]['Month'], 
                             y=grouped[grouped['Year'] == year]['UnidadesVendidas'], 
                             name='UnidadesVendidas ' + str(year), 
                             yaxis='y2',
                             line_color=line_color))

# Configurando os eixos e a legenda
fig.update_layout(
    title={
        'text': "Unidades Vendidas e Valor Total por Mês e Ano",
        'y':0.9,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'}, 
    xaxis=dict(title='Month'),
    yaxis=dict(title='ValorTotal'),
    yaxis2=dict(title='UnidadesVendidas', overlaying='y', side='right'),
    autosize=False,
    width=900,  # Diminui a largura do gráfico em 10%
    legend=dict(
        x=1.1,  # Posiciona a legenda mais para a direita
        y=1,  # Posiciona a legenda no topo
        bgcolor='rgba(255, 255, 255, 0)',  # Fundo transparente para a legenda
        bordercolor='rgba(255, 255, 255, 0)'  # Borda transparente para a legenda
    )
)

fig.show()
In [ ]:
# Preenchendo os valores nulos na coluna 'Promo' com 0
df_t['Promo'] = df_t['Promo'].fillna(0)

# Convertendo a coluna 'Promo' para float, substituindo NaNs por 0 e depois convertendo para inteiro
df_t['Promo'] = np.nan_to_num(df_t['Promo'].astype(float)).astype(int)

# Filtrando os dados para os anos de 2022 e 2023
df_t['Year'] = df_t['Data'].dt.year
df_t['Month'] = df_t['Data'].dt.month
df_filtered = df_t[df_t['Year'].isin([2022, 2023])]

# Criando a tabela agregada
pivot = df_filtered.pivot_table(index='Month', columns='Year', values=['ValorTotal', 'UnidadesVendidas', 'Promo'], aggfunc='sum')

# Adicionando a linha com o valor total
pivot.loc['Total'] = pivot.sum()

pivot
Out[ ]:
Promo UnidadesVendidas ValorTotal
Year 2022 2023 2022 2023 2022 2023
Month
1 39.0 17.0 1014.0 829.0 48038.830 42374.9645
2 31.0 28.0 725.0 744.0 33487.866 37752.1970
3 62.0 25.0 1455.0 1023.0 67337.112 54805.5775
4 37.0 15.0 1034.0 886.0 48180.612 45134.3005
5 45.0 20.0 1077.0 914.0 51761.596 46058.3785
6 26.0 16.0 715.0 1213.0 33658.754 64254.3245
7 48.0 23.0 1044.0 1079.0 48442.970 58027.6275
8 59.0 23.0 1126.0 968.0 50768.534 53043.2705
9 35.0 28.0 848.0 1246.0 40119.278 65966.1620
Total 382.0 195.0 9038.0 8902.0 421795.552 467416.8025
In [ ]:
# Extraindo a linha 'Total'
total_values = pivot.loc['Total']

# Transpondo a série para um DataFrame e resetando o índice
total_df = total_values.transpose().reset_index()

# Renomeando as colunas
total_df.columns = ['Category', 'Year', 'Value']

# Pivotando o DataFrame
pivot_total = total_df.pivot(index='Category', columns='Year', values='Value')

# Calculando a mudança percentual
pivot_total['Change (%)'] = (pivot_total[2023] - pivot_total[2022]) / pivot_total[2022] * 100

pivot_total
Out[ ]:
Year 2022 2023 Change (%)
Category
Promo 382.000 195.0000 -48.952880
UnidadesVendidas 9038.000 8902.0000 -1.504758
ValorTotal 421795.552 467416.8025 10.815963
In [ ]:
# o ano de 2023 teve menos promoções 
# e menos Unidades vendidas em relação a 2022, 
# porém obteve um Valor Total maior 
# indicando que houve um Ticket Médio maior em 2023 em relação a 2022
In [ ]:
# Calculando o Ticket Médio para cada ano
pivot_total['Ticket Médio 2022'] = pivot_total[2022]['ValorTotal'] / pivot_total[2022]['UnidadesVendidas']
pivot_total['Ticket Médio 2023'] = pivot_total[2023]['ValorTotal'] / pivot_total[2023]['UnidadesVendidas']

# Exibindo o DataFrame
pivot_total
Out[ ]:
Year 2022 2023 Change (%) Ticket Médio 2022 Ticket Médio 2023
Category
Promo 382.000 195.0000 -48.952880 46.669125 52.506943
UnidadesVendidas 9038.000 8902.0000 -1.504758 46.669125 52.506943
ValorTotal 421795.552 467416.8025 10.815963 46.669125 52.506943
In [ ]:
import matplotlib.pyplot as plt

# Definindo o tamanho da figura
fig, ax = plt.subplots(figsize=(15, 10))  # Aumentando a largura da figura

# Adicionando a tabela à figura
table_data = pivot_total.reset_index().round(2).values.tolist()  # Arredondando os valores para 2 casas decimais
column_labels = pivot_total.reset_index().columns.tolist()

# Definindo as cores
colors = sns.color_palette("Pastel2").as_hex()

# Criando uma matriz de cores
cell_colors = [[colors[i%len(colors)] for _ in row] for i, row in enumerate(table_data)]

# Adicionando a tabela à figura
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc = 'center', loc='center', cellColours=cell_colors)

# Ajustando o tamanho da fonte
table.auto_set_font_size(False)
table.set_fontsize(14)

# Ajustando o tamanho da fonte dos cabeçalhos
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(10)

# Ajustando a largura das colunas e a altura das linhas
table.scale(1.2, 1.5)  # Aumentando a largura das colunas e a altura das linhas

# Escondendo os eixos
ax.axis('off')

# Salvando a figura como .png
plt.savefig('pivot_total_table.png')
No description has been provided for this image
In [ ]:
# Calculate 'Ticket Médio' for 2022 and 2023
pivot[('Ticket Médio', 2022)] = pivot[('ValorTotal', 2022)] / pivot[('UnidadesVendidas', 2022)]
pivot[('Ticket Médio', 2023)] = pivot[('ValorTotal', 2023)] / pivot[('UnidadesVendidas', 2023)]

# Display the updated DataFrame
pivot
Out[ ]:
Promo UnidadesVendidas ValorTotal Ticket Médio
Year 2022 2023 2022 2023 2022 2023 2022 2023
Month
1 39.0 17.0 1014.0 829.0 48038.830 42374.9645 47.375572 51.115759
2 31.0 28.0 725.0 744.0 33487.866 37752.1970 46.190160 50.742200
3 62.0 25.0 1455.0 1023.0 67337.112 54805.5775 46.279802 53.573390
4 37.0 15.0 1034.0 886.0 48180.612 45134.3005 46.596337 50.941648
5 45.0 20.0 1077.0 914.0 51761.596 46058.3785 48.060906 50.392099
6 26.0 16.0 715.0 1213.0 33658.754 64254.3245 47.075180 52.971413
7 48.0 23.0 1044.0 1079.0 48442.970 58027.6275 46.401312 53.779080
8 59.0 23.0 1126.0 968.0 50768.534 53043.2705 45.087508 54.796767
9 35.0 28.0 848.0 1246.0 40119.278 65966.1620 47.310469 52.942345
Total 382.0 195.0 9038.0 8902.0 421795.552 467416.8025 46.669125 52.506943
In [ ]:
# Definindo o tamanho da figura
fig, ax = plt.subplots(figsize=(15, 10))  # Aumentando a largura da figura

# Adicionando a tabela à figura
table_data = pivot.reset_index().round(2).values.tolist()  # Arredondando os valores para 2 casas decimais
column_labels = pivot.reset_index().columns.tolist()

# Definindo as cores
colors = sns.color_palette("Pastel2").as_hex()

# Criando uma matriz de cores
cell_colors = [[colors[i%len(colors)] for _ in row] for i, row in enumerate(table_data)]

# Adicionando a tabela à figura
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc = 'center', loc='center', cellColours=cell_colors)

# Ajustando o tamanho da fonte
table.auto_set_font_size(False)
table.set_fontsize(16)

# Ajustando o tamanho da fonte dos cabeçalhos
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(13)

# Ajustando a largura das colunas e a altura das linhas
table.scale(2, 1.8)  # Aumentando a largura das colunas e a altura das linhas

# Escondendo os eixos
ax.axis('off')

# Salvando a figura como .png
plt.savefig('pivot_table_with_ticket_medio.png')
No description has been provided for this image
In [ ]:
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Define a list of colors
colors = ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc']

# Calcular o Ticket Médio
df_t['Ticket Médio'] = df_t['ValorTotal'] / df_t['UnidadesVendidas']

# Agrupar os dados e calcular a média
df_grouped = df_t.groupby(['Year', 'Month']).agg({'UnidadesVendidas': 'sum', 'ValorTotal': 'sum', 'Promo': 'sum', 'Ticket Médio': 'mean'}).reset_index()

# Obter o número de colunas
num_cols = len(df_grouped.columns) - 2  # Subtrair as colunas 'Year' e 'Month'

# Calcular o número de linhas e colunas para os subplots
num_rows = num_cols // 2 if num_cols % 2 == 0 else num_cols // 2 + 1

# Criar subplots
fig = make_subplots(rows=num_rows, cols=2, subplot_titles=df_grouped.columns[2:])

# Adicionar traços
for i, header in enumerate(df_grouped.columns[2:]):
    row = i // 2 + 1
    col = i % 2 + 1
    for j, year in enumerate(df_grouped['Year'].unique()):
        df_year = df_grouped[df_grouped['Year'] == year]
        fig.add_trace(go.Scatter(x=df_year['Month'], y=df_year[header], mode='lines', name=f'{header} {year}', line=dict(color=colors[j % len(colors)])), row=row, col=col)

# Atualizar layout
fig.update_layout(height=600, width=800, title_text="Subplots")
fig.show()

Segunda parte da análise:¶

  • explorando os dados de transações com as Marcas e suas categorias
nesta segunda parte da análise é possível verificar que:¶
O top vermelho gammaz - teve ótimo desempenho,¶
- ficou em segundo lugar no rank de Ticket Médio (TM) no ano de 2023. Caiu 1 posição em relação a 2022¶
- se manteve em primeiro em relação a Unidades Vendidas e Valor Total (VT) 2022 e 2023¶
- fez menos promoções em 2023 em relação a 2022 - caiu de sexto em quantidade de promoções para sétimo¶
mas o Botton azul Gammaz também teve destaque!¶
2023 Bottom Azul Marca GammaZ -> TM - 88.517723 VT - 75759.52¶
2023 Top Vermelho Marca GammaZ -> TM - 83.774699 VT - 146329.22¶
O Botton azul gammaz que não foi vendido em 2022 teve um desempenho melhor em 2023 quando se olha pra Ticket Médio.¶
A Marca Gammaz no geral teve um bom desempenho pra Ticket Médio e Valor Total, ultrapassando em Valor Total a Marca AlfaX¶
As promoções não impulsionaram o negócio de forma geral¶
Cores vermelhas são representativas em vendas, mas um destaque foram peças azuis, que melhoraram tanto em quantidade vendida, quanto em aumento de ticket médio e valor Total¶
Houve crescimento de Ticket médio de peças tipo Botton e também Valor Total, o que ajuda a explicar o sucesso do Botton azul gammaz¶
In [ ]:
# O top vermelho gammaz - teve ótimo desempenho, mas o Botton azul Gammaz também teve destaque
# - ficou em segundo lugar no rank de Ticket Médio no ano de 2023. Caiu 1 posição em relação a 2022
# - se manteve em primeiro em relação a Unidades Vendidas e Valor Total 2022 e 2023
# - fez menos promoções em 2023 em relação a 2022 - caiu de sexto em quantidade de promoções para sétimo

# 2023	Bottom Azul Marca GammaZ	TM - 88.517723	VT - 75759.52
# 2023	Top Vermelho Marca GammaZ	TM - 83.774699	VT - 146329.22

# O Botton azul gammaz que não foi vendido em 2022 teve um desempenho melhor em 2023 quando se olha pra Ticket Médio.

# A Marca Gammaz no geral teve um bom desempenho pra Ticket Médio e Valor Total, ultrapassando em Valor Total a Marca AlfaX
 
# As promoções não impulsionaram o negócio de forma geral

# Cores vermelhas são representativas em vendas, mas um destaque foram peças azuis que melhoraram tanto em quantidade vendida quanto em aumento de ticket médio e valor Total

# Houve crescimento de Ticket médio de peças tipo Botton e também Valor Total, o que ajuda a explicar o sucesso do Botton azul gammaz
In [ ]:
import openpyxl
import pandas as pd

# arquivo
wb = openpyxl.load_workbook('Exercicio_Python_CRM .xlsx', read_only=True)

# aba de produto
ws = wb['Produto']

# tamanho do chunk para leitura de bases grandes
chunk_size = 100000
chunks = []

# cabeçalho (nomes das colunas) da primeira linha
header = [cell.value for cell in ws[1]]

# dados em chunks para bases com milhões de linhas
for i in range(2, ws.max_row, chunk_size):  # Comecça de 2 porque a primeira linha é o cabeçalho
    rows = ws[i:i + chunk_size]
    data = [[cell.value for cell in row] for row in rows]
    df = pd.DataFrame(data, columns=header)  # Usando o cabeçalho como nomes das colunas
    chunks.append(df)

# Concatenando os chunks em um único DataFrame
df_p = pd.concat(chunks, axis=0)

# Para cada coluna no DataFrame
for col in df_p.columns:
    # Se o tipo de dados da coluna é object (string)
    if df_p[col].dtype == 'object':
        # Remova os espaços em branco no início e no final  
        df_p[col] = df_p[col].str.strip()
In [ ]:
df_p.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 12 entries, 0 to 11
Data columns (total 5 columns):
 #   Column             Non-Null Count  Dtype 
---  ------             --------------  ----- 
 0   ID_Produto         12 non-null     int64 
 1   Descrição Produto  12 non-null     object
 2   Categoria          12 non-null     object
 3   Cor                12 non-null     object
 4   Marca              12 non-null     object
dtypes: int64(1), object(4)
memory usage: 608.0+ bytes
In [ ]:
# verificando valores nulos
null_counts = df_p.isnull().sum()
print(null_counts)
ID_Produto           0
Descrição Produto    0
Categoria            0
Cor                  0
Marca                0
dtype: int64
In [ ]:
# verificando valores duplicados

for column in df_p.columns:
    print(f"\nColumn: {column}")
    print(df_p[column].value_counts(dropna=False))
Column: ID_Produto
123000    1
123001    1
123002    1
123003    1
123004    1
123005    1
123006    1
123007    1
123008    1
123009    1
123010    1
123011    1
Name: ID_Produto, dtype: int64

Column: Descrição Produto
Top Marca GammaZ            2
Bottom Azul Marca AlfaX     1
Top Cinza Marca GammaZ      1
Bottom Preto Marca BetaY    1
Top Marca BetaY             1
Top Cinza Marca BetaY       1
Top Cinza Marca AlfaX       1
Bottom Preto Marca AlfaX    1
Top Marca AlfaX             1
Bottom GammaZ               1
Bottom BetaY                1
Name: Descrição Produto, dtype: int64

Column: Categoria
Top       7
Bottom    5
Name: Categoria, dtype: int64

Column: Cor
Vermelho    4
Azul        3
Cinza       3
Preto       2
Name: Cor, dtype: int64

Column: Marca
AlfaX     4
GammaZ    4
BetaY     4
Name: Marca, dtype: int64
In [ ]:
df_p
Out[ ]:
ID_Produto Descrição Produto Categoria Cor Marca
0 123000 Bottom Azul Marca AlfaX Bottom Azul AlfaX
1 123001 Top Cinza Marca GammaZ Top Cinza GammaZ
2 123002 Bottom Preto Marca BetaY Bottom Preto BetaY
3 123003 Top Marca BetaY Top Vermelho BetaY
4 123004 Top Cinza Marca BetaY Top Cinza BetaY
5 123005 Top Cinza Marca AlfaX Top Cinza AlfaX
6 123006 Bottom Preto Marca AlfaX Bottom Preto AlfaX
7 123007 Top Marca AlfaX Top Vermelho AlfaX
8 123008 Top Marca GammaZ Top Vermelho GammaZ
9 123009 Top Marca GammaZ Top Vermelho GammaZ
10 123010 Bottom GammaZ Bottom Azul GammaZ
11 123011 Bottom BetaY Bottom Azul BetaY
In [ ]:
def update_description(row):
    if row['Categoria'] not in row['Descrição Produto']:
        row['Descrição Produto'] = row['Categoria'] + ' ' + row['Descrição Produto']
    if row['Cor'] not in row['Descrição Produto']:
        row['Descrição Produto'] = row['Descrição Produto'].replace(row['Categoria'], row['Categoria'] + ' ' + row['Cor'])
    if 'Marca' not in row['Descrição Produto'] and row['Marca'] not in row['Descrição Produto']:
        row['Descrição Produto'] = row['Descrição Produto'].replace(row['Marca'], 'Marca ' + row['Marca'])
    return row

df_p = df_p.apply(update_description, axis=1)

df_p.loc[df_p['ID_Produto'] == 123010, 'Descrição Produto'] = 'Bottom Azul Marca GammaZ'
df_p.loc[df_p['ID_Produto'] == 123011, 'Descrição Produto'] = 'Bottom Azul Marca BetaY'
In [ ]:
df_p
Out[ ]:
ID_Produto Descrição Produto Categoria Cor Marca
0 123000 Bottom Azul Marca AlfaX Bottom Azul AlfaX
1 123001 Top Cinza Marca GammaZ Top Cinza GammaZ
2 123002 Bottom Preto Marca BetaY Bottom Preto BetaY
3 123003 Top Vermelho Marca BetaY Top Vermelho BetaY
4 123004 Top Cinza Marca BetaY Top Cinza BetaY
5 123005 Top Cinza Marca AlfaX Top Cinza AlfaX
6 123006 Bottom Preto Marca AlfaX Bottom Preto AlfaX
7 123007 Top Vermelho Marca AlfaX Top Vermelho AlfaX
8 123008 Top Vermelho Marca GammaZ Top Vermelho GammaZ
9 123009 Top Vermelho Marca GammaZ Top Vermelho GammaZ
10 123010 Bottom Azul Marca GammaZ Bottom Azul GammaZ
11 123011 Bottom Azul Marca BetaY Bottom Azul BetaY
In [ ]:
df_t['ID_Produto'].value_counts(dropna=False)
Out[ ]:
123004    850
123005    842
123003    828
123002    824
123008    822
123006    806
123007    795
123001    639
123009    592
123010    380
123000    228
123011    185
Name: ID_Produto, dtype: int64
In [ ]:
df_p['ID_Produto'].value_counts(dropna=False)
Out[ ]:
123000    1
123001    1
123002    1
123003    1
123004    1
123005    1
123006    1
123007    1
123008    1
123009    1
123010    1
123011    1
Name: ID_Produto, dtype: int64
In [ ]:
#left join
df_tp = pd.merge(df_t, df_p, on='ID_Produto', how='left')
In [ ]:
df_tp.head()
Out[ ]:
ID_Trans Data ID_Loja ID_Produto ID_Cliente UnidadesVendidas ValorTotal Promo Year Month Ticket Médio Descrição Produto Categoria Cor Marca
0 1 2022-01-01 7 123005 90023 2 99.98 0 2022 1 49.99 Top Cinza Marca AlfaX Top Cinza AlfaX
1 2 2022-01-01 9 123004 90092 1 35.99 0 2022 1 35.99 Top Cinza Marca BetaY Top Cinza BetaY
2 3 2022-01-01 1 123001 90027 2 51.98 0 2022 1 25.99 Top Cinza Marca GammaZ Top Cinza GammaZ
3 4 2022-01-01 3 123001 90097 2 51.98 0 2022 1 25.99 Top Cinza Marca GammaZ Top Cinza GammaZ
4 5 2022-01-01 4 123004 90089 2 71.98 0 2022 1 35.99 Top Cinza Marca BetaY Top Cinza BetaY
In [ ]:
# liberando memória
del df_t
In [ ]:
df_tp.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 7791 entries, 0 to 7790
Data columns (total 15 columns):
 #   Column             Non-Null Count  Dtype         
---  ------             --------------  -----         
 0   ID_Trans           7791 non-null   int64         
 1   Data               7791 non-null   datetime64[ns]
 2   ID_Loja            7791 non-null   int64         
 3   ID_Produto         7791 non-null   int64         
 4   ID_Cliente         7791 non-null   int64         
 5   UnidadesVendidas   7791 non-null   int64         
 6   ValorTotal         7791 non-null   float64       
 7   Promo              7791 non-null   int32         
 8   Year               7791 non-null   int64         
 9   Month              7791 non-null   int64         
 10  Ticket Médio       7791 non-null   float64       
 11  Descrição Produto  7791 non-null   object        
 12  Categoria          7791 non-null   object        
 13  Cor                7791 non-null   object        
 14  Marca              7791 non-null   object        
dtypes: datetime64[ns](1), float64(2), int32(1), int64(7), object(4)
memory usage: 943.4+ KB
In [ ]:
# Drop unnecessary columns
df_tp_drp = df_tp.drop(columns=['ID_Trans', 'Data', 'ID_Loja', 'ID_Produto', 'ID_Cliente', 'Month'])

# Group by 'Descrição Produto', 'Categoria', 'Cor', 'Marca', and 'Year' and calculate the mean of 'Ticket Médio' and the sum of 'UnidadesVendidas', 'ValorTotal', and 'Promo'
grouped_df = df_tp_drp.groupby(['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Year']).agg({'Ticket Médio': 'mean', 'UnidadesVendidas': 'sum', 'ValorTotal': 'sum', 'Promo': 'sum'}).reset_index()

grouped_df
Out[ ]:
Descrição Produto Categoria Cor Marca Year Ticket Médio UnidadesVendidas ValorTotal Promo
0 Bottom Azul Marca AlfaX Bottom Azul AlfaX 2022 19.845445 531 10528.7830 0
1 Bottom Azul Marca BetaY Bottom Azul BetaY 2023 19.763070 419 8270.8580 0
2 Bottom Azul Marca GammaZ Bottom Azul GammaZ 2023 88.517723 857 75759.5210 14
3 Bottom Preto Marca AlfaX Bottom Preto AlfaX 2022 55.165527 985 54301.4730 56
4 Bottom Preto Marca AlfaX Bottom Preto AlfaX 2023 54.385049 870 47305.1560 24
5 Bottom Preto Marca BetaY Bottom Preto BetaY 2022 27.667022 1023 28352.3420 66
6 Bottom Preto Marca BetaY Bottom Preto BetaY 2023 27.845801 903 25165.8615 27
7 Top Cinza Marca AlfaX Top Cinza AlfaX 2022 49.136522 968 47560.4940 0
8 Top Cinza Marca AlfaX Top Cinza AlfaX 2023 42.473845 943 40015.9045 35
9 Top Cinza Marca BetaY Top Cinza BetaY 2022 35.473874 1041 36928.5670 70
10 Top Cinza Marca BetaY Top Cinza BetaY 2023 35.661356 929 33147.6245 28
11 Top Cinza Marca GammaZ Top Cinza GammaZ 2022 25.926545 984 25364.7560 74
12 Top Cinza Marca GammaZ Top Cinza GammaZ 2023 24.851804 455 11289.7375 20
13 Top Vermelho Marca AlfaX Top Vermelho AlfaX 2022 58.892622 980 57740.3750 0
14 Top Vermelho Marca AlfaX Top Vermelho AlfaX 2023 59.345082 887 52698.2030 1
15 Top Vermelho Marca BetaY Top Vermelho BetaY 2022 27.469110 1045 28709.3430 82
16 Top Vermelho Marca BetaY Top Vermelho BetaY 2023 30.761997 891 27434.7070 30
17 Top Vermelho Marca GammaZ Top Vermelho GammaZ 2022 89.344289 1481 132309.4190 34
18 Top Vermelho Marca GammaZ Top Vermelho GammaZ 2023 83.774699 1748 146329.2295 16
In [ ]:
grouped_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 19 entries, 0 to 18
Data columns (total 9 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   Descrição Produto  19 non-null     object 
 1   Categoria          19 non-null     object 
 2   Cor                19 non-null     object 
 3   Marca              19 non-null     object 
 4   Year               19 non-null     int64  
 5   Ticket Médio       19 non-null     float64
 6   UnidadesVendidas   19 non-null     int64  
 7   ValorTotal         19 non-null     float64
 8   Promo              19 non-null     int32  
dtypes: float64(2), int32(1), int64(2), object(4)
memory usage: 1.4+ KB
In [ ]:
# Filter the DataFrame by year and create two separate DataFrames
df1 = grouped_df[grouped_df['Year'] == 2022].copy()
df2 = grouped_df[grouped_df['Year'] == 2023].copy()

# Create a rank of 'UnidadesVendidas' in each DataFrame
df1['Rank_2022_UnidadesVendidas'] = df1['UnidadesVendidas'].rank(ascending=False)
df2['Rank_2023_UnidadesVendidas'] = df2['UnidadesVendidas'].rank(ascending=False)

# Merge the two DataFrames using a full outer join, bringing only the rank columns
rank_UnidadesVendidas = pd.merge(df1[['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Rank_2022_UnidadesVendidas']], 
                                 df2[['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Rank_2023_UnidadesVendidas']], 
                                 on=['Descrição Produto', 'Categoria', 'Cor', 'Marca'], 
                                 how='outer')

# Sort the DataFrame by 'Rank_2023_UnidadesVendidas'
rank_UnidadesVendidas = rank_UnidadesVendidas.sort_values('Rank_2023_UnidadesVendidas')

rank_UnidadesVendidas
Out[ ]:
Descrição Produto Categoria Cor Marca Rank_2022_UnidadesVendidas Rank_2023_UnidadesVendidas
8 Top Vermelho Marca GammaZ Top Vermelho GammaZ 1.0 1.0
3 Top Cinza Marca AlfaX Top Cinza AlfaX 8.0 2.0
4 Top Cinza Marca BetaY Top Cinza BetaY 3.0 3.0
2 Bottom Preto Marca BetaY Bottom Preto BetaY 4.0 4.0
7 Top Vermelho Marca BetaY Top Vermelho BetaY 2.0 5.0
6 Top Vermelho Marca AlfaX Top Vermelho AlfaX 7.0 6.0
1 Bottom Preto Marca AlfaX Bottom Preto AlfaX 5.0 7.0
10 Bottom Azul Marca GammaZ Bottom Azul GammaZ NaN 8.0
5 Top Cinza Marca GammaZ Top Cinza GammaZ 6.0 9.0
9 Bottom Azul Marca BetaY Bottom Azul BetaY NaN 10.0
0 Bottom Azul Marca AlfaX Bottom Azul AlfaX 9.0 NaN
In [ ]:
# Filter the DataFrame by year and create two separate DataFrames
df1 = grouped_df[grouped_df['Year'] == 2022].copy()
df2 = grouped_df[grouped_df['Year'] == 2023].copy()

# Create a rank of 'ValorTotal' in each DataFrame
df1['Rank_2022_ValorTotal'] = df1['ValorTotal'].rank(ascending=False)
df2['Rank_2023_ValorTotal'] = df2['ValorTotal'].rank(ascending=False)

# Merge the two DataFrames using a full outer join, bringing only the rank columns
rank_ValorTotal = pd.merge(df1[['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Rank_2022_ValorTotal']], 
                           df2[['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Rank_2023_ValorTotal']], 
                           on=['Descrição Produto', 'Categoria', 'Cor', 'Marca'], 
                           how='outer')

# Sort the DataFrame by 'Rank_2023_ValorTotal'
rank_ValorTotal = rank_ValorTotal.sort_values('Rank_2023_ValorTotal')

rank_ValorTotal
Out[ ]:
Descrição Produto Categoria Cor Marca Rank_2022_ValorTotal Rank_2023_ValorTotal
8 Top Vermelho Marca GammaZ Top Vermelho GammaZ 1.0 1.0
10 Bottom Azul Marca GammaZ Bottom Azul GammaZ NaN 2.0
6 Top Vermelho Marca AlfaX Top Vermelho AlfaX 2.0 3.0
1 Bottom Preto Marca AlfaX Bottom Preto AlfaX 3.0 4.0
3 Top Cinza Marca AlfaX Top Cinza AlfaX 4.0 5.0
4 Top Cinza Marca BetaY Top Cinza BetaY 5.0 6.0
7 Top Vermelho Marca BetaY Top Vermelho BetaY 6.0 7.0
2 Bottom Preto Marca BetaY Bottom Preto BetaY 7.0 8.0
5 Top Cinza Marca GammaZ Top Cinza GammaZ 8.0 9.0
9 Bottom Azul Marca BetaY Bottom Azul BetaY NaN 10.0
0 Bottom Azul Marca AlfaX Bottom Azul AlfaX 9.0 NaN
In [ ]:
# Filter the DataFrame by year and create two separate DataFrames
df1 = grouped_df[grouped_df['Year'] == 2022].copy()
df2 = grouped_df[grouped_df['Year'] == 2023].copy()

# Create a rank of 'Promo' in each DataFrame
df1['Rank_2022_Promo'] = df1['Promo'].rank(ascending=False)
df2['Rank_2023_Promo'] = df2['Promo'].rank(ascending=False)

# Merge the two DataFrames using a full outer join, bringing only the rank columns
rank_Promo = pd.merge(df1[['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Rank_2022_Promo']], 
                      df2[['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Rank_2023_Promo']], 
                      on=['Descrição Produto', 'Categoria', 'Cor', 'Marca'], 
                      how='outer')

# Sort the DataFrame by 'Rank_2023_Promo'
rank_Promo = rank_Promo.sort_values('Rank_2023_Promo')

rank_Promo
Out[ ]:
Descrição Produto Categoria Cor Marca Rank_2022_Promo Rank_2023_Promo
3 Top Cinza Marca AlfaX Top Cinza AlfaX 8.0 1.0
7 Top Vermelho Marca BetaY Top Vermelho BetaY 1.0 2.0
4 Top Cinza Marca BetaY Top Cinza BetaY 3.0 3.0
2 Bottom Preto Marca BetaY Bottom Preto BetaY 4.0 4.0
1 Bottom Preto Marca AlfaX Bottom Preto AlfaX 5.0 5.0
5 Top Cinza Marca GammaZ Top Cinza GammaZ 2.0 6.0
8 Top Vermelho Marca GammaZ Top Vermelho GammaZ 6.0 7.0
10 Bottom Azul Marca GammaZ Bottom Azul GammaZ NaN 8.0
6 Top Vermelho Marca AlfaX Top Vermelho AlfaX 8.0 9.0
9 Bottom Azul Marca BetaY Bottom Azul BetaY NaN 10.0
0 Bottom Azul Marca AlfaX Bottom Azul AlfaX 8.0 NaN
In [ ]:
# Filter the DataFrame by year and create two separate DataFrames
df1 = grouped_df[grouped_df['Year'] == 2022].copy()
df2 = grouped_df[grouped_df['Year'] == 2023].copy()

# Create a rank of 'Ticket Médio' in each DataFrame
df1['Rank_2022_Ticket_Medio'] = df1['Ticket Médio'].rank(ascending=False)
df2['Rank_2023_Ticket_Medio'] = df2['Ticket Médio'].rank(ascending=False)

# Merge the two DataFrames using a full outer join, bringing only the rank columns
rank_Ticket_Medio = pd.merge(df1[['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Rank_2022_Ticket_Medio']], 
                             df2[['Descrição Produto', 'Categoria', 'Cor', 'Marca', 'Rank_2023_Ticket_Medio']], 
                             on=['Descrição Produto', 'Categoria', 'Cor', 'Marca'], 
                             how='outer')

# Sort the DataFrame by 'Rank_2023_Ticket_Medio'
rank_Ticket_Medio = rank_Ticket_Medio.sort_values('Rank_2023_Ticket_Medio')

rank_Ticket_Medio
Out[ ]:
Descrição Produto Categoria Cor Marca Rank_2022_Ticket_Medio Rank_2023_Ticket_Medio
10 Bottom Azul Marca GammaZ Bottom Azul GammaZ NaN 1.0
8 Top Vermelho Marca GammaZ Top Vermelho GammaZ 1.0 2.0
6 Top Vermelho Marca AlfaX Top Vermelho AlfaX 2.0 3.0
1 Bottom Preto Marca AlfaX Bottom Preto AlfaX 3.0 4.0
3 Top Cinza Marca AlfaX Top Cinza AlfaX 4.0 5.0
4 Top Cinza Marca BetaY Top Cinza BetaY 5.0 6.0
7 Top Vermelho Marca BetaY Top Vermelho BetaY 7.0 7.0
2 Bottom Preto Marca BetaY Bottom Preto BetaY 6.0 8.0
5 Top Cinza Marca GammaZ Top Cinza GammaZ 8.0 9.0
9 Bottom Azul Marca BetaY Bottom Azul BetaY NaN 10.0
0 Bottom Azul Marca AlfaX Bottom Azul AlfaX 9.0 NaN
In [ ]:
# Drop 'Categoria' and 'Marca' columns
rank_UnidadesVendidas = rank_UnidadesVendidas.drop(['Categoria', 'Marca','Cor'], axis=1)
rank_ValorTotal = rank_ValorTotal.drop(['Categoria', 'Marca','Cor'], axis=1)
rank_Promo = rank_Promo.drop(['Categoria', 'Marca','Cor'], axis=1)
rank_Ticket_Medio = rank_Ticket_Medio.drop(['Categoria', 'Marca','Cor'], axis=1)

# Merge all DataFrames
merged_df = rank_UnidadesVendidas.merge(rank_ValorTotal, how='outer', on=['Descrição Produto'])
merged_df = merged_df.merge(rank_Promo, how='outer', on=['Descrição Produto'])
merged_df = merged_df.merge(rank_Ticket_Medio, how='outer', on=['Descrição Produto'])

# Sort by 'Rank_2023_Ticket_Medio'
merged_df = merged_df.sort_values(by='Rank_2023_Ticket_Medio')
In [ ]:
cols = ['Descrição Produto', 'Rank_2022_Ticket_Medio', 'Rank_2023_Ticket_Medio'] + [col for col in merged_df.columns if col not in ['Descrição Produto', 'Rank_2022_Ticket_Medio', 'Rank_2023_Ticket_Medio']]
merged_df = merged_df[cols]
In [ ]:
merged_df.head(4)
Out[ ]:
Descrição Produto Rank_2022_Ticket_Medio Rank_2023_Ticket_Medio Rank_2022_UnidadesVendidas Rank_2023_UnidadesVendidas Rank_2022_ValorTotal Rank_2023_ValorTotal Rank_2022_Promo Rank_2023_Promo
7 Bottom Azul Marca GammaZ NaN 1.0 NaN 8.0 NaN 2.0 NaN 8.0
0 Top Vermelho Marca GammaZ 1.0 2.0 1.0 1.0 1.0 1.0 6.0 7.0
5 Top Vermelho Marca AlfaX 2.0 3.0 7.0 6.0 2.0 3.0 8.0 9.0
6 Bottom Preto Marca AlfaX 3.0 4.0 5.0 7.0 3.0 4.0 5.0 5.0
In [ ]:
# Define a dictionary for the new column names
new_column_names = {
    'Rank_2022_Ticket_Medio': 'Rank_22_TM',
    'Rank_2023_Ticket_Medio': 'Rank_23_TM',
    'Rank_2022_UnidadesVendidas': 'Rank_22_UV',
    'Rank_2023_UnidadesVendidas': 'Rank_23_UV',
    'Rank_2022_ValorTotal': 'Rank_22_VT',
    'Rank_2023_ValorTotal': 'Rank_23_VT',
    'Rank_2022_Promo': 'Rank_22_Pro',
    'Rank_2023_Promo': 'Rank_23_Pro',
    'Descrição Produto': 'DescProduto'
}

# Rename the columns
merged_df.rename(columns=new_column_names, inplace=True)
In [ ]:
merged_df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 11 entries, 7 to 10
Data columns (total 9 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   DescProduto  11 non-null     object 
 1   Rank_22_TM   9 non-null      float64
 2   Rank_23_TM   10 non-null     float64
 3   Rank_22_UV   9 non-null      float64
 4   Rank_23_UV   10 non-null     float64
 5   Rank_22_VT   9 non-null      float64
 6   Rank_23_VT   10 non-null     float64
 7   Rank_22_Pro  9 non-null      float64
 8   Rank_23_Pro  10 non-null     float64
dtypes: float64(8), object(1)
memory usage: 880.0+ bytes
In [ ]:
# Defining the figure size
fig, ax = plt.subplots(figsize=(15, 10))

# Adding the table to the figure
table_data = merged_df.reset_index().round(2).values.tolist()
column_labels = merged_df.reset_index().columns.tolist()

# Defining the colors
colors = sns.color_palette("Pastel2").as_hex()

# Creating a color matrix
cell_colors = [[colors[i%len(colors)] for _ in row] for i, row in enumerate(table_data)]

# Adding the table to the figure
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc = 'center', loc='center', cellColours=cell_colors)

# Adjusting the font size
table.auto_set_font_size(False)
table.set_fontsize(16)

# Increase the overall width and height of the table
table.scale(4, 3.5)  # Increase the first value to increase the width, and the second value to increase the height

# Increase the font size
table.set_fontsize(20)

# Adjust the font size of the headers
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(15)

# Adjust the font size of 'DescProduto' column
for key, cell in table.get_celld().items():
    if key[1] == 0:  # 0 is the index of 'DescProduto' column
        cell.set_fontsize(14)  # Increase this value to make the text larger
# Hiding the axes
ax.axis('off')

# Saving the figure as .png
plt.savefig('merged_df_table.png')
No description has been provided for this image
In [ ]:
# Create DataFrame with columns that contain '2022'
df_2022 = merged_df.filter(regex='DesProduto|2022')

# Create DataFrame with columns that contain '2023'
df_2023 = merged_df.filter(regex='DesProduto|2023')
In [ ]:
import plotly.figure_factory as ff

# Create DataFrame with columns that contain '22'
df_2022 = merged_df.filter(regex='22')

# Create DataFrame with columns that contain '23'
df_2023 = merged_df.filter(regex='23')

# Create correlation matrices and round to 3 decimal places
correlation_matrix_2022 = df_2022.corr().round(3)
correlation_matrix_2023 = df_2023.corr().round(3)

# Create heatmaps with 'BluGrn' color scale and smaller font size
heatmap_2022 = ff.create_annotated_heatmap(z=correlation_matrix_2022.values, 
                                           x=list(correlation_matrix_2022.columns), 
                                           y=list(correlation_matrix_2022.index), 
                                           colorscale='BluGrn', 
                                           font_colors=['black', 'white'], 
                                           annotation_text=correlation_matrix_2022.values.astype(str))

heatmap_2023 = ff.create_annotated_heatmap(z=correlation_matrix_2023.values, 
                                           x=list(correlation_matrix_2023.columns), 
                                           y=list(correlation_matrix_2023.index), 
                                           colorscale='BluGrn', 
                                           font_colors=['black', 'white'], 
                                           annotation_text=correlation_matrix_2023.values.astype(str))

# Add titles
heatmap_2022.update_layout(title='Heatmap 2022')
heatmap_2023.update_layout(title='Heatmap 2023')

# Decrease the size of the axis labels
heatmap_2022.update_xaxes(tickfont=dict(size=10))
heatmap_2022.update_yaxes(tickfont=dict(size=10))
heatmap_2023.update_xaxes(tickfont=dict(size=10))
heatmap_2023.update_yaxes(tickfont=dict(size=10))

# Display heatmaps
heatmap_2022.show()
heatmap_2023.show()
In [ ]:
# Group by 'Year' and 'Marca' and calculate the sum of 'ValorTotal' and the mean of 'Ticket Médio'
df_Marca = df_tp.groupby(['Year', 'Marca']).agg({'ValorTotal': 'sum', 'Ticket Médio': 'mean'}).reset_index()

# Display the new DataFrame
print(df_Marca)
   Year   Marca   ValorTotal  Ticket Médio
0  2022   AlfaX  170131.1250     49.049442
1  2022   BetaY   93990.2520     30.261648
2  2022  GammaZ  157674.1750     63.811702
3  2023   AlfaX  140019.2635     51.688359
4  2023   BetaY   94019.0510     29.848488
5  2023  GammaZ  233378.4880     76.131544
In [ ]:
# Group by 'Year' and 'Marca' and calculate the sum of 'ValorTotal' and the mean of 'Ticket Médio'
df_Marca_ = df_tp.groupby(['Year', 'Marca']).agg({'Promo': 'sum', 'UnidadesVendidas': 'sum'}).reset_index()
In [ ]:
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create a subplot with 1 row and 2 columns, with titles for spacing
fig = make_subplots(rows=1, cols=2, subplot_titles=("",""))

# Define colors for each year
colors = {'2022': ['rgb(179,226,205)', 'rgb(253,205,172)'], '2023': ['rgb(102,194,165)', 'rgb(252,141,98)']}

# Get the unique years
years = df_Marca['Year'].unique()

# For each year
for i, year in enumerate(years):
    # Filter the DataFrame for the current year
    df_year = df_Marca[df_Marca['Year'] == year]

    # Create a bar plot for 'Ticket Médio'
    fig.add_trace(go.Bar(x=df_year['Marca'], y=df_year['Ticket Médio'], name='Ticket Médio ' + str(year), marker_color=colors[str(year)][0]), row=1, col=1)

    # Create a bar plot for 'ValorTotal'
    fig.add_trace(go.Bar(x=df_year['Marca'], y=df_year['ValorTotal'], name='ValorTotal ' + str(year), marker_color=colors[str(year)][1]), row=1, col=2)

# Update xaxis and yaxis properties
fig.update_xaxes(title_text="Marca", row=1, col=1)
fig.update_xaxes(title_text="Marca", row=1, col=2)
fig.update_yaxes(title_text="Ticket Médio", row=1, col=1)
fig.update_yaxes(title_text="ValorTotal", row=1, col=2)

# Update layout to group bars instead of stacking, increase figure width, and adjust subplot spacing
fig.update_layout(barmode='group', width=1200, margin=dict(b=100))

# Show the figure
fig.show()
In [ ]:
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create a subplot with 1 row and 2 columns, with titles for spacing
fig = make_subplots(rows=1, cols=2, subplot_titles=("",""))

# Define colors for each year
colors = {'2022': ['rgb(179,226,205)', 'rgb(253,205,172)'], '2023': ['rgb(102,194,165)', 'rgb(252,141,98)']}

# Get the unique years
years = df_Marca_['Year'].unique()

# For each year
for i, year in enumerate(years):
    # Filter the DataFrame for the current year
    df_year = df_Marca_[df_Marca_['Year'] == year]

    # Create a bar plot for 'Promo'
    fig.add_trace(go.Bar(x=df_year['Marca'], y=df_year['Promo'], name='Promo ' + str(year), marker_color=colors[str(year)][0]), row=1, col=1)

    # Create a bar plot for 'UnidadesVendidas'
    fig.add_trace(go.Bar(x=df_year['Marca'], y=df_year['UnidadesVendidas'], name='UnidadesVendidas ' + str(year), marker_color=colors[str(year)][1]), row=1, col=2)

# Update xaxis and yaxis properties
fig.update_xaxes(title_text="Marca", row=1, col=1)
fig.update_xaxes(title_text="Marca", row=1, col=2)
fig.update_yaxes(title_text="Promo", row=1, col=1)
fig.update_yaxes(title_text="UnidadesVendidas", row=1, col=2)

# Update layout to group bars instead of stacking, increase figure width, and adjust subplot spacing
fig.update_layout(barmode='group', width=1200, margin=dict(b=100))

# Show the figure
fig.show()
In [ ]:
# GammaZ tem o maior Ticket Médio em 2022 e 2023 e ultrapasou a marca AlphaX em 2023 em relação ao Valor Total
# As promoções não teem efeito significativo nas vendas de UnidadesVendidas para nenhuma das marcas em 2022 e 2023
In [ ]:
# Group by 'Year' and 'Cor' and calculate the sum of 'ValorTotal' and the mean of 'Ticket Médio'
df_Cor = df_tp.groupby(['Year', 'Cor']).agg({'ValorTotal': 'sum', 'Ticket Médio': 'mean'}).reset_index()

# Group by 'Year' and 'Cor' and calculate the sum of 'Promo' and 'UnidadesVendidas'
df_Cor_ = df_tp.groupby(['Year', 'Cor']).agg({'Promo': 'sum', 'UnidadesVendidas': 'sum'}).reset_index()
In [ ]:
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create a subplot with 1 row and 2 columns, with titles for spacing
fig = make_subplots(rows=1, cols=2, subplot_titles=("",""))

# Define colors for each year
colors = {'2022': ['rgb(179,226,205)', 'rgb(253,205,172)'], '2023': ['rgb(102,194,165)', 'rgb(252,141,98)']}

# Get the unique years
years = df_Cor['Year'].unique()

# For each year
for i, year in enumerate(years):
    # Filter the DataFrame for the current year
    df_year = df_Cor[df_Cor['Year'] == year]

    # Create a bar plot for 'Ticket Médio'
    fig.add_trace(go.Bar(x=df_year['Cor'], y=df_year['Ticket Médio'], name='Ticket Médio ' + str(year), marker_color=colors[str(year)][0]), row=1, col=1)

    # Create a bar plot for 'ValorTotal'
    fig.add_trace(go.Bar(x=df_year['Cor'], y=df_year['ValorTotal'], name='ValorTotal ' + str(year), marker_color=colors[str(year)][1]), row=1, col=2)

# Update xaxis and yaxis properties
fig.update_xaxes(title_text="Cor", row=1, col=1)
fig.update_xaxes(title_text="Cor", row=1, col=2)
fig.update_yaxes(title_text="Ticket Médio", row=1, col=1)
fig.update_yaxes(title_text="ValorTotal", row=1, col=2)

# Update layout to group bars instead of stacking, increase figure width, and adjust subplot spacing
fig.update_layout(barmode='group', width=1200, margin=dict(b=100))

# Show the figure
fig.show()
In [ ]:
# Create a subplot with 1 row and 2 columns, with titles for spacing
fig = make_subplots(rows=1, cols=2, subplot_titles=("",""))

# Define colors for each year
colors = {'2022': ['rgb(179,226,205)', 'rgb(253,205,172)'], '2023': ['rgb(102,194,165)', 'rgb(252,141,98)']}

# Get the unique years
years = df_Cor_['Year'].unique()

# For each year
for i, year in enumerate(years):
    # Filter the DataFrame for the current year
    df_year = df_Cor_[df_Cor_['Year'] == year]

    # Create a bar plot for 'Promo'
    fig.add_trace(go.Bar(x=df_year['Cor'], y=df_year['Promo'], name='Promo ' + str(year), marker_color=colors[str(year)][0]), row=1, col=1)

    # Create a bar plot for 'UnidadesVendidas'
    fig.add_trace(go.Bar(x=df_year['Cor'], y=df_year['UnidadesVendidas'], name='UnidadesVendidas ' + str(year), marker_color=colors[str(year)][1]), row=1, col=2)

# Update xaxis and yaxis properties
fig.update_xaxes(title_text="Cor", row=1, col=1)
fig.update_xaxes(title_text="Cor", row=1, col=2)
fig.update_yaxes(title_text="Promo", row=1, col=1)
fig.update_yaxes(title_text="UnidadesVendidas", row=1, col=2)

# Update layout to group bars instead of stacking, increase figure width, and adjust subplot spacing
fig.update_layout(barmode='group', width=1200, margin=dict(b=100))

# Show the figure
fig.show()
In [ ]:
# apenas a cor azul respondeu positivamente a promoções em 2023 em relação a unidades vendidas
In [ ]:
# Group by 'Year' and 'Categoria' and calculate the sum of 'ValorTotal' and the mean of 'Ticket Médio'
df_Categoria = df_tp.groupby(['Year', 'Categoria']).agg({'ValorTotal': 'sum', 'Ticket Médio': 'mean'}).reset_index()

# Group by 'Year' and 'Categoria' and calculate the sum of 'Promo' and 'UnidadesVendidas'
df_Categoria_ = df_tp.groupby(['Year', 'Categoria']).agg({'Promo': 'sum', 'UnidadesVendidas': 'sum'}).reset_index()
In [ ]:
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create a subplot with 1 row and 2 columns, with titles for spacing
fig = make_subplots(rows=1, cols=2, subplot_titles=("",""))

# Define colors for each year
colors = {'2022': ['rgb(179,226,205)', 'rgb(253,205,172)'], '2023': ['rgb(102,194,165)', 'rgb(252,141,98)']}

# Get the unique years
years = df_Categoria['Year'].unique()

# For each year
for i, year in enumerate(years):
    # Filter the DataFrame for the current year
    df_year = df_Categoria[df_Categoria['Year'] == year]

    # Create a bar plot for 'Ticket Médio'
    fig.add_trace(go.Bar(x=df_year['Categoria'], y=df_year['Ticket Médio'], name='Ticket Médio ' + str(year), marker_color=colors[str(year)][0]), row=1, col=1)

    # Create a bar plot for 'ValorTotal'
    fig.add_trace(go.Bar(x=df_year['Categoria'], y=df_year['ValorTotal'], name='ValorTotal ' + str(year), marker_color=colors[str(year)][1]), row=1, col=2)

# Update xaxis and yaxis properties
fig.update_xaxes(title_text="Categoria", row=1, col=1)
fig.update_xaxes(title_text="Categoria", row=1, col=2)
fig.update_yaxes(title_text="Ticket Médio", row=1, col=1)
fig.update_yaxes(title_text="ValorTotal", row=1, col=2)

# Update layout to group bars instead of stacking, increase figure width, and adjust subplot spacing
fig.update_layout(barmode='group', width=1200, margin=dict(b=100))

# Show the figure
fig.show()
In [ ]:
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create a subplot with 1 row and 2 columns, with titles for spacing
fig = make_subplots(rows=1, cols=2, subplot_titles=("",""))

# Define colors for each year
colors = {'2022': ['rgb(179,226,205)', 'rgb(253,205,172)'], '2023': ['rgb(102,194,165)', 'rgb(252,141,98)']}

# Get the unique years
years = df_Categoria_['Year'].unique()

# For each year
for i, year in enumerate(years):
    # Filter the DataFrame for the current year
    df_year = df_Categoria_[df_Categoria_['Year'] == year]

    # Create a bar plot for 'Promo'
    fig.add_trace(go.Bar(x=df_year['Categoria'], y=df_year['Promo'], name='Promo ' + str(year), marker_color=colors[str(year)][0]), row=1, col=1)

    # Create a bar plot for 'UnidadesVendidas'
    fig.add_trace(go.Bar(x=df_year['Categoria'], y=df_year['UnidadesVendidas'], name='UnidadesVendidas ' + str(year), marker_color=colors[str(year)][1]), row=1, col=2)

# Update xaxis and yaxis properties
fig.update_xaxes(title_text="Categoria", row=1, col=1)
fig.update_xaxes(title_text="Categoria", row=1, col=2)
fig.update_yaxes(title_text="Promo", row=1, col=1)
fig.update_yaxes(title_text="UnidadesVendidas", row=1, col=2)

# Update layout to group bars instead of stacking, increase figure width, and adjust subplot spacing
fig.update_layout(barmode='group', width=1200, margin=dict(b=100))

# Show the figure
fig.show()
In [ ]:
# Group by 'Year' and 'Descrição Produto' and calculate the sum of 'ValorTotal' and the mean of 'Ticket Médio'
df_Descrição_Produto = df_tp.groupby(['Year', 'Descrição Produto']).agg({'ValorTotal': 'sum', 'Ticket Médio': 'mean'}).reset_index()

# Group by 'Year' and 'Descrição Produto' and calculate the sum of 'Promo' and 'UnidadesVendidas'
df_Descrição_Produto_ = df_tp.groupby(['Year', 'Descrição Produto']).agg({'Promo': 'sum', 'UnidadesVendidas': 'sum'}).reset_index()
In [ ]:
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create a subplot with 1 row and 2 columns, with titles for spacing
fig = make_subplots(rows=1, cols=2, subplot_titles=("",""))

# Define colors for each year
colors = {'2022': ['rgb(179,226,205)', 'rgb(253,205,172)'], '2023': ['rgb(102,194,165)', 'rgb(252,141,98)']}

# Get the unique years
years = df_Descrição_Produto['Year'].unique()

# For each year
for i, year in enumerate(years):
    # Filter the DataFrame for the current year
    df_year = df_Descrição_Produto[df_Descrição_Produto['Year'] == year]

    # Create a bar plot for 'Ticket Médio'
    fig.add_trace(go.Bar(x=df_year['Descrição Produto'], y=df_year['Ticket Médio'], name='Ticket Médio ' + str(year), marker_color=colors[str(year)][0]), row=1, col=1)

    # Create a bar plot for 'ValorTotal'
    fig.add_trace(go.Bar(x=df_year['Descrição Produto'], y=df_year['ValorTotal'], name='ValorTotal ' + str(year), marker_color=colors[str(year)][1]), row=1, col=2)

# Update xaxis and yaxis properties
fig.update_xaxes(title_text="Descrição Produto", row=1, col=1)
fig.update_xaxes(title_text="Descrição Produto", row=1, col=2)
fig.update_yaxes(title_text="Ticket Médio", row=1, col=1)
fig.update_yaxes(title_text="ValorTotal", row=1, col=2)

# Update layout to group bars instead of stacking, increase figure width, and adjust subplot spacing
fig.update_layout(barmode='group', width=1200, margin=dict(b=100))

# Show the figure
fig.show()
In [ ]:
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Create a subplot with 1 row and 2 columns, with titles for spacing
fig = make_subplots(rows=1, cols=2, subplot_titles=("",""))

# Define colors for each year
colors = {'2022': ['rgb(179,226,205)', 'rgb(253,205,172)'], '2023': ['rgb(102,194,165)', 'rgb(252,141,98)']}

# Get the unique years
years = df_Descrição_Produto_['Year'].unique()

# For each year
for i, year in enumerate(years):
    # Filter the DataFrame for the current year
    df_year = df_Descrição_Produto_[df_Descrição_Produto_['Year'] == year]

    # Create a bar plot for 'Promo'
    fig.add_trace(go.Bar(x=df_year['Descrição Produto'], y=df_year['Promo'], name='Promo ' + str(year), marker_color=colors[str(year)][0]), row=1, col=1)

    # Create a bar plot for 'UnidadesVendidas'
    fig.add_trace(go.Bar(x=df_year['Descrição Produto'], y=df_year['UnidadesVendidas'], name='UnidadesVendidas ' + str(year), marker_color=colors[str(year)][1]), row=1, col=2)

# Update xaxis and yaxis properties
fig.update_xaxes(title_text="Descrição Produto", row=1, col=1)
fig.update_xaxes(title_text="Descrição Produto", row=1, col=2)
fig.update_yaxes(title_text="Promo", row=1, col=1)
fig.update_yaxes(title_text="UnidadesVendidas", row=1, col=2)

# Update layout to group bars instead of stacking, increase figure width, and adjust subplot spacing
fig.update_layout(barmode='group', width=1200, margin=dict(b=100))

# Show the figure
fig.show()
In [ ]:
import itertools 
# Get unique products and years
products = df_tp['Descrição Produto'].unique()
years = df_tp['Year'].unique()

# Create subplots
fig, axs = plt.subplots(len(products)*len(years), 3, figsize=(15, 5*len(products)*len(years)))

for i, (product, year) in enumerate(itertools.product(products, years)):
    # Filter DataFrame by product and year
    df_product_year = df_tp[(df_tp['Descrição Produto'] == product) & (df_tp['Year'] == year)]

    # Create distribution plots
    sns.distplot(df_product_year['Ticket Médio'], ax=axs[i, 0])
    sns.distplot(df_product_year['UnidadesVendidas'], ax=axs[i, 1])
    sns.distplot(df_product_year['ValorTotal'], ax=axs[i, 2])

    # Set titles
    axs[i, 0].set_title(f'Ticket Médio - {product} - {year}')
    axs[i, 1].set_title(f'UnidadesVendidas - {product} - {year}')
    axs[i, 2].set_title(f'ValorTotal - {product} - {year}')

plt.tight_layout()
plt.show()
c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2657: RuntimeWarning:

Mean of empty slice.

c:\Users\surze\anaconda3\lib\site-packages\numpy\core\_methods.py:189: RuntimeWarning:

invalid value encountered in double_scalars

c:\Users\surze\anaconda3\lib\site-packages\numpy\lib\histograms.py:906: RuntimeWarning:

invalid value encountered in true_divide

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

c:\Users\surze\anaconda3\lib\site-packages\seaborn\distributions.py:2619: FutureWarning:

`distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).

No description has been provided for this image
In [ ]:
import plotly.graph_objects as go

def create_plot_for_brand(brand):
    # Get unique products and years for the brand
    products = df_tp[df_tp['Marca'] == brand]['Descrição Produto'].unique()
    years = sorted(df_tp[df_tp['Marca'] == brand]['Year'].unique())

    # Define color sequence
    colors = ['#66c2a5','#fc8d62','#8da0cb','#e78ac3','#a6d854','#ffd92f']

    # Create a dictionary to map years to colors
    year_color = {year: colors[i % len(colors)] for i, year in enumerate(years)}

    # Create dictionaries to store mean 'Ticket Médio' and sum 'UnidadesVendidas', 'ValorTotal' and 'Promo' for each product and year
    ticket_medio_means = {year: {} for year in years}
    unidades_vendidas_sums = {year: {} for year in years}
    valor_total_sums = {year: {} for year in years}
    promo_sums = {year: {} for year in years}

    fig = go.Figure()
    for year in years:
        for product in products:
            # Filter DataFrame by product and year
            df_product_year = df_tp[(df_tp['Marca'] == brand) & (df_tp['Descrição Produto'] == product) & (df_tp['Year'] == year)]

            # Calculate mean 'Ticket Médio' and sum 'UnidadesVendidas', 'ValorTotal' and 'Promo'
            ticket_medio_mean = df_product_year['Ticket Médio'].mean()
            unidades_vendidas_sum = df_product_year['UnidadesVendidas'].sum()
            valor_total_sum = df_product_year['ValorTotal'].sum()
            promo_sum = df_product_year['Promo'].sum()

            # Store these values in the dictionaries
            ticket_medio_means[year][product] = ticket_medio_mean
            unidades_vendidas_sums[year][product] = unidades_vendidas_sum
            valor_total_sums[year][product] = valor_total_sum
            promo_sums[year][product] = promo_sum

        # Add a bar or line to the chart depending on the year
        if year == 2022:
            fig.add_trace(go.Bar(x=products, y=[ticket_medio_means[year][product] for product in products], name=f'{year}', marker_color=year_color[year],
                                 hovertemplate='Ticket Médio: %{y:.2f}<br>Unidades Vendidas: %{customdata[0]:.2f}<br>Valor Total: %{customdata[1]:.2f}<br>Promo: %{customdata[2]:.2f}<extra></extra>',
                                 customdata=[[unidades_vendidas_sums[year][product], valor_total_sums[year][product], promo_sums[year][product]] for product in products]))
        elif year == 2023:
            # Calculate percentage variation from 2022 to 2023 for each product
            percent_variations = [(ticket_medio_means[year][product] / ticket_medio_means[2022][product] - 1) * 100 for product in products]

            fig.add_trace(go.Scatter(x=products, y=[ticket_medio_means[year][product] for product in products], mode='lines', name=f'{year}', line=dict(color=year_color[year]),
                                     hovertemplate='Ticket Médio: %{y:.2f}<br>Variation from 2022: %{customdata[0]:.2f}%<br>Unidades Vendidas: %{customdata[1]:.2f}<br>Valor Total: %{customdata[2]:.2f}<br>Promo: %{customdata[3]:.2f}<extra></extra>',
                                     customdata=[[percent_variations[i], unidades_vendidas_sums[year][product], valor_total_sums[year][product], promo_sums[year][product]] for i, product in enumerate(products)]))

    # Update layout
    fig.update_layout(
        height=600, 
        width=900, 
        title_text=f"Ticket Médio for {brand}", 
        xaxis_title="Descrição Produto", 
        yaxis_title="Ticket Médio", 
        barmode='group',
        xaxis_tickangle=-90
    )

    # Show plot
    fig.show()

# Get unique brands
brands = df_tp['Marca'].unique()

# Create a plot for each brand
for brand in brands:
    create_plot_for_brand(brand)
In [ ]:
# grouped = df_sorted.groupby('Year')

# for name, group in grouped:
#     print(f"Year: {name}")
#     display(group)
In [ ]:
df_tp.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 7791 entries, 0 to 7790
Data columns (total 15 columns):
 #   Column             Non-Null Count  Dtype         
---  ------             --------------  -----         
 0   ID_Trans           7791 non-null   int64         
 1   Data               7791 non-null   datetime64[ns]
 2   ID_Loja            7791 non-null   int64         
 3   ID_Produto         7791 non-null   int64         
 4   ID_Cliente         7791 non-null   int64         
 5   UnidadesVendidas   7791 non-null   int64         
 6   ValorTotal         7791 non-null   float64       
 7   Promo              7791 non-null   int32         
 8   Year               7791 non-null   int64         
 9   Month              7791 non-null   int64         
 10  Ticket Médio       7791 non-null   float64       
 11  Descrição Produto  7791 non-null   object        
 12  Categoria          7791 non-null   object        
 13  Cor                7791 non-null   object        
 14  Marca              7791 non-null   object        
dtypes: datetime64[ns](1), float64(2), int32(1), int64(7), object(4)
memory usage: 943.4+ KB
In [ ]:
pivot_df = df_tp.pivot_table(index=['Marca', 'Descrição Produto'], columns='Year', values=['Ticket Médio', 'ValorTotal', 'UnidadesVendidas'])
In [ ]:
pivot_df.info()
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 11 entries, ('AlfaX', 'Bottom Azul Marca AlfaX') to ('GammaZ', 'Top Vermelho Marca GammaZ')
Data columns (total 6 columns):
 #   Column                    Non-Null Count  Dtype  
---  ------                    --------------  -----  
 0   (Ticket Médio, 2022)      9 non-null      float64
 1   (Ticket Médio, 2023)      10 non-null     float64
 2   (UnidadesVendidas, 2022)  9 non-null      float64
 3   (UnidadesVendidas, 2023)  10 non-null     float64
 4   (ValorTotal, 2022)        9 non-null      float64
 5   (ValorTotal, 2023)        10 non-null     float64
dtypes: float64(6)
memory usage: 806.0+ bytes
In [ ]:
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import pandas as pd

# pivot_df = df_tp.pivot_table(index=['Marca', 'Descrição Produto'], columns='Year', values=['Ticket Médio', 'ValorTotal', 'UnidadesVendidas'])

for col in ['Ticket Médio', 'ValorTotal', 'UnidadesVendidas']:
    pivot_df[(col, 'Variação 2022-2023')] = ((pivot_df[(col, 2023)] - pivot_df[(col, 2022)]) / pivot_df[(col, 2022)]) * 100

pivot_df = pivot_df.fillna(0)

pivot_df = pivot_df.reindex([
    ('Ticket Médio', 2022),
    ('Ticket Médio', 2023),
    ('Ticket Médio', 'Variação 2022-2023'),
    ('UnidadesVendidas', 2022),
    ('UnidadesVendidas', 2023),
    ('UnidadesVendidas', 'Variação 2022-2023'),
    ('ValorTotal', 2022),
    ('ValorTotal', 2023),
    ('ValorTotal', 'Variação 2022-2023')
], axis=1)

# Defining the figure size
fig, ax = plt.subplots(figsize=(15, 10))

# Adding the table to the figure
table_data = pivot_df.reset_index().round(2).values.tolist()
column_labels = pivot_df.reset_index().columns.tolist()

# Get the Pastel2 colormap
colors = cm.get_cmap('Pastel2').colors  # This gets the RGBA values of the colors
colors = [cm.colors.to_hex(c) for c in colors]  # This converts the RGBA values to hexadecimal color codes

# Create a color dictionary for each 'Marca'
marca_colors = {marca: colors[i % len(colors)] for i, marca in enumerate(pivot_df.index.get_level_values('Marca').unique())}

# Create a color matrix based on 'Marca'
cell_colors = [[marca_colors[row[0]] for _ in row] for row in table_data]

# Adding the table to the figure
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc = 'center', loc='center', cellColours=cell_colors)

# Adjusting the font size
table.auto_set_font_size(False)
table.set_fontsize(20)  # Increase this value to make the text larger

# Increase the overall width and height of the table
table.scale(6, 5)  # Increase these values to increase the width and height of the columns

# Adjust the font size of the headers
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(25)  # Increase this value to make the text larger

# Adjust the font size of 'Marca' and 'Descrição Produto' columns
for key, cell in table.get_celld().items():
    if key[1] in [0, 1]:  # 0 and 1 are the indices of 'Marca' and 'Descrição Produto' columns
        cell.set_fontsize(22)  # Increase this value to make the text larger

# Hiding the axes
ax.axis('off')

# Saving the figure as .png
plt.savefig('pivot_df_table.png')
No description has been provided for this image
In [ ]:
pivot_df
Out[ ]:
Ticket Médio UnidadesVendidas ValorTotal
Year 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023
Marca Descrição Produto
AlfaX Bottom Azul Marca AlfaX 19.845445 0.000000 0.000000 2.328947 0.000000 0.000000 46.178873 0.000000 0.000000
Bottom Preto Marca AlfaX 55.165527 54.385049 -1.414794 2.328605 2.271540 -2.450597 128.372277 123.512157 -3.785958
Top Cinza Marca AlfaX 49.136522 42.473845 -13.559522 2.360976 2.182870 -7.543714 116.001205 92.629409 -20.147891
Top Vermelho Marca AlfaX 58.892622 59.345082 0.768280 2.390244 2.303896 -3.612510 140.830183 136.878449 -2.806027
BetaY Bottom Azul Marca BetaY 0.000000 19.763070 0.000000 0.000000 2.264865 0.000000 0.000000 44.707341 0.000000
Bottom Preto Marca BetaY 27.667022 27.845801 0.646178 2.368056 2.303571 -2.723083 65.630421 64.198626 -2.181603
Top Cinza Marca BetaY 35.473874 35.661356 0.528506 2.292952 2.345960 2.311783 81.340456 83.706122 2.908352
Top Vermelho Marca BetaY 27.469110 30.761997 11.987600 2.343049 2.332461 -0.451915 64.370724 71.818605 11.570292
GammaZ Bottom Azul Marca GammaZ 0.000000 88.517723 0.000000 0.000000 2.255263 0.000000 0.000000 199.367161 0.000000
Top Cinza Marca GammaZ 25.926545 24.851804 -4.145330 2.277778 2.198068 -3.499470 58.714713 54.539795 -7.110515
Top Vermelho Marca GammaZ 89.344289 83.774699 -6.233851 2.310452 2.261320 -2.126548 206.410950 189.300426 -8.289543
In [ ]:
# liberando espaço na memória
# Get a dictionary of all variables in your current namespace
variables = locals()

# Convert the items to a list before iterating
for var_name, var_value in list(variables.items()):
    if isinstance(var_value, pd.DataFrame) and var_name != 'df_tp':
        del variables[var_name]
Quarta parte da análise:¶
  • Clientes e Lojas
nesta quarta parte da análise é possível verificar que:¶
  • As lojas 5(SP), 8(RS) e 2(MG) foram as que melhor performaram em relação a Ticket Médio no ano de 2023
  • Para estas lojas a Classe B é a com maior Ticket Médio no ano de 2023 e o sexo feminino se destaca neste quesito
  • nas faixas etárias há um diferença entre as lojas quando se trata de Ticket Médio no ano de 2023

loja 5 -> 18-25 loja 8 -> 25-35 loja 2 -> 45+

  • as tabelas trazem detalhes que podem auxiliar em decisões futuras de MKT de froma mais detalhada
In [ ]:
import openpyxl
import pandas as pd

# arquivo
wb = openpyxl.load_workbook('Exercicio_Python_CRM .xlsx', read_only=True)

# aba de Cliente
ws = wb['Cliente']

# tamanho do chunk para leitura de bases grandes
chunk_size = 100000
chunks = []

# cabeçalho (nomes das colunas) da primeira linha
header = [cell.value for cell in ws[1]]

# dados em chunks para bases com milhões de linhas
for i in range(2, ws.max_row, chunk_size):  # Comecça de 2 porque a primeira linha é o cabeçalho
    rows = ws[i:i + chunk_size]
    data = [[cell.value for cell in row] for row in rows]
    df = pd.DataFrame(data, columns=header)  # Usando o cabeçalho como nomes das colunas
    chunks.append(df)

# Concatenando os chunks em um único DataFrame
df_c = pd.concat(chunks, axis=0)

# Para cada coluna no DataFrame
for col in df_c.columns:
    # Se o tipo de dados da coluna é object (string)
    if pd.api.types.is_object_dtype(df_c[col]):
        # Remova os espaços em branco no início e no final
        df_c[col] = df_c[col].str.strip()
In [ ]:
import openpyxl
import pandas as pd

# arquivo
wb = openpyxl.load_workbook('Exercicio_Python_CRM .xlsx', read_only=True)

# aba de Cliente
ws = wb['Lojas']

# tamanho do chunk para leitura de bases grandes
chunk_size = 100000
chunks = []

# cabeçalho (nomes das colunas) da primeira linha
header = [cell.value for cell in ws[1]]

# dados em chunks para bases com milhões de linhas
for i in range(2, ws.max_row, chunk_size):  # Comecça de 2 porque a primeira linha é o cabeçalho
    rows = ws[i:i + chunk_size]
    data = [[cell.value for cell in row] for row in rows]
    df = pd.DataFrame(data, columns=header)  # Usando o cabeçalho como nomes das colunas
    chunks.append(df)

# Concatenando os chunks em um único DataFrame
df_l = pd.concat(chunks, axis=0)

# Para cada coluna no DataFrame
for col in df_l.columns:
    # Se o tipo de dados da coluna é object (string)
    if pd.api.types.is_object_dtype(df_l[col]):
        # Remova os espaços em branco no início e no final
        df_l[col] = df_l[col].str.strip()
In [ ]:
df_l.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 3 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   ID_Loja  10 non-null     int64 
 1   UF       10 non-null     object
 2   Regiao   8 non-null      object
dtypes: int64(1), object(2)
memory usage: 368.0+ bytes
In [ ]:
df_l
Out[ ]:
ID_Loja UF Regiao
0 1 AM NORTE
1 2 MG CENTRO-OESTE
2 3 SP SUDESTE
3 4 SP None
4 5 SP SUDESTE
5 6 SP SUDESTE
6 7 RS SUL
7 8 RS SUL
8 9 BH NORDESTE
9 10 BH None
In [ ]:
# If 'Regiao' is None and 'UF' is 'SP', set 'Regiao' to 'SUDESTE'
df_l.loc[(df_l['Regiao'].isnull()) & (df_l['UF'] == 'SP'), 'Regiao'] = 'SUDESTE'

# If 'Regiao' is None and 'UF' is 'BH', set 'Regiao' to 'SUDESTE'
df_l.loc[(df_l['Regiao'].isnull()) & (df_l['UF'] == 'BH'), 'Regiao'] = 'SUDESTE'
In [ ]:
df_l
Out[ ]:
ID_Loja UF Regiao
0 1 AM NORTE
1 2 MG CENTRO-OESTE
2 3 SP SUDESTE
3 4 SP SUDESTE
4 5 SP SUDESTE
5 6 SP SUDESTE
6 7 RS SUL
7 8 RS SUL
8 9 BH NORDESTE
9 10 BH SUDESTE
In [ ]:
df_c.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 8 columns):
 #   Column        Non-Null Count  Dtype 
---  ------        --------------  ----- 
 0   CustomerID    100 non-null    int64 
 1   Genero        93 non-null     object
 2   FaixaIdade    100 non-null    object
 3   ClasseSocial  100 non-null    object
 4   None          0 non-null      object
 5   None          0 non-null      object
 6   None          0 non-null      object
 7   None          0 non-null      object
dtypes: int64(1), object(7)
memory usage: 6.4+ KB
In [ ]:
df_c = df_c.dropna(axis=1, how='all')
df_c[df_c['Genero'].isnull()]
for col in df_c.columns:
    print(f'Column: {col}')
    print(df_c[col].value_counts(dropna=False))
Column: CustomerID
90000    1
90063    1
90073    1
90072    1
90071    1
        ..
90030    1
90029    1
90028    1
90027    1
90099    1
Name: CustomerID, Length: 100, dtype: int64
Column: Genero
Feminino     64
Masculino    29
None          7
Name: Genero, dtype: int64
Column: FaixaIdade
25-35    50
35-45    30
18-25    11
45+       9
Name: FaixaIdade, dtype: int64
Column: ClasseSocial
C    52
D    15
B    12
A    11
E    10
Name: ClasseSocial, dtype: int64
In [ ]:
df_c.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 4 columns):
 #   Column        Non-Null Count  Dtype 
---  ------        --------------  ----- 
 0   CustomerID    100 non-null    int64 
 1   Genero        93 non-null     object
 2   FaixaIdade    100 non-null    object
 3   ClasseSocial  100 non-null    object
dtypes: int64(1), object(3)
memory usage: 3.2+ KB
In [ ]:
df_tp.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 7791 entries, 0 to 7790
Data columns (total 15 columns):
 #   Column             Non-Null Count  Dtype         
---  ------             --------------  -----         
 0   ID_Trans           7791 non-null   int64         
 1   Data               7791 non-null   datetime64[ns]
 2   ID_Loja            7791 non-null   int64         
 3   ID_Produto         7791 non-null   int64         
 4   ID_Cliente         7791 non-null   int64         
 5   UnidadesVendidas   7791 non-null   int64         
 6   ValorTotal         7791 non-null   float64       
 7   Promo              7791 non-null   int32         
 8   Year               7791 non-null   int64         
 9   Month              7791 non-null   int64         
 10  Ticket Médio       7791 non-null   float64       
 11  Descrição Produto  7791 non-null   object        
 12  Categoria          7791 non-null   object        
 13  Cor                7791 non-null   object        
 14  Marca              7791 non-null   object        
dtypes: datetime64[ns](1), float64(2), int32(1), int64(7), object(4)
memory usage: 943.4+ KB
In [ ]:
# Perform a left join of df_tp and df_l on the 'ID_Loja' column
df_merged = df_tp.merge(df_l, on='ID_Loja', how='left')
In [ ]:
df_merged.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 7791 entries, 0 to 7790
Data columns (total 17 columns):
 #   Column             Non-Null Count  Dtype         
---  ------             --------------  -----         
 0   ID_Trans           7791 non-null   int64         
 1   Data               7791 non-null   datetime64[ns]
 2   ID_Loja            7791 non-null   int64         
 3   ID_Produto         7791 non-null   int64         
 4   ID_Cliente         7791 non-null   int64         
 5   UnidadesVendidas   7791 non-null   int64         
 6   ValorTotal         7791 non-null   float64       
 7   Promo              7791 non-null   int32         
 8   Year               7791 non-null   int64         
 9   Month              7791 non-null   int64         
 10  Ticket Médio       7791 non-null   float64       
 11  Descrição Produto  7791 non-null   object        
 12  Categoria          7791 non-null   object        
 13  Cor                7791 non-null   object        
 14  Marca              7791 non-null   object        
 15  UF                 7791 non-null   object        
 16  Regiao             7791 non-null   object        
dtypes: datetime64[ns](1), float64(2), int32(1), int64(7), object(6)
memory usage: 1.0+ MB
In [ ]:
# Perform a left join of df_merged and df_c on the 'ID_Cliente' and 'CustomerID' columns
df_final = df_merged.merge(df_c, left_on='ID_Cliente', right_on='CustomerID', how='left')
In [ ]:
df_final.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 7791 entries, 0 to 7790
Data columns (total 21 columns):
 #   Column             Non-Null Count  Dtype         
---  ------             --------------  -----         
 0   ID_Trans           7791 non-null   int64         
 1   Data               7791 non-null   datetime64[ns]
 2   ID_Loja            7791 non-null   int64         
 3   ID_Produto         7791 non-null   int64         
 4   ID_Cliente         7791 non-null   int64         
 5   UnidadesVendidas   7791 non-null   int64         
 6   ValorTotal         7791 non-null   float64       
 7   Promo              7791 non-null   int32         
 8   Year               7791 non-null   int64         
 9   Month              7791 non-null   int64         
 10  Ticket Médio       7791 non-null   float64       
 11  Descrição Produto  7791 non-null   object        
 12  Categoria          7791 non-null   object        
 13  Cor                7791 non-null   object        
 14  Marca              7791 non-null   object        
 15  UF                 7791 non-null   object        
 16  Regiao             7791 non-null   object        
 17  CustomerID         7791 non-null   int64         
 18  Genero             7251 non-null   object        
 19  FaixaIdade         7791 non-null   object        
 20  ClasseSocial       7791 non-null   object        
dtypes: datetime64[ns](1), float64(2), int32(1), int64(8), object(9)
memory usage: 1.3+ MB
In [ ]:
# liberando espaço na memória
# Get a dictionary of all variables in your current namespace
variables = locals()

# Convert the items to a list before iterating
for var_name, var_value in list(variables.items()):
    if isinstance(var_value, pd.DataFrame) and var_name != 'df_final':
        del variables[var_name]
In [ ]:
# Group by 'ID_Loja' and 'Year' and calculate the mean of 'Ticket Médio', 'ValorTotal', and 'UnidadesVendidas'
df_grouped = df_final.groupby(['ID_Loja', 'Year']).agg({'Ticket Médio': 'mean', 'ValorTotal': 'sum', 'UnidadesVendidas': 'sum'})

# Rank 'ID_Loja' by 'Ticket Médio', 'ValorTotal', and 'UnidadesVendidas' for each year
df_grouped['Rank_Ticket_Medio'] = df_grouped.groupby('Year')['Ticket Médio'].rank(ascending=False)
df_grouped['Rank_ValorTotal'] = df_grouped.groupby('Year')['ValorTotal'].rank(ascending=False)
df_grouped['Rank_UnidadesVendidas'] = df_grouped.groupby('Year')['UnidadesVendidas'].rank(ascending=False)
In [ ]:
# Sort df_grouped by 'ID_Loja', 'Year' and 'Rank_Ticket_Medio'
df_sorted = df_grouped.sort_values(by=['ID_Loja', 'Rank_Ticket_Medio', 'Year'])

# Print the sorted DataFrame
df_sorted
Out[ ]:
Ticket Médio ValorTotal UnidadesVendidas Rank_Ticket_Medio Rank_ValorTotal Rank_UnidadesVendidas
ID_Loja Year
1 2022 47.247530 24933.3660 530 3.0 9.0 9.0
2023 53.186719 24882.2255 476 4.0 10.0 10.0
2 2023 54.171854 54148.3405 997 3.0 2.0 3.0
2022 45.367873 46666.1960 1041 10.0 4.0 3.0
3 2022 46.916761 51070.6560 1093 5.0 1.0 1.0
2023 52.052152 55391.3810 1062 7.0 1.0 1.0
4 2022 47.407694 50145.1960 1054 2.0 2.0 2.0
2023 52.388917 50037.4375 965 5.0 6.0 6.0
5 2023 54.538466 51742.8740 954 1.0 5.0 7.0
2022 46.310672 43168.7600 918 7.0 7.0 8.0
6 2022 47.123065 46405.7300 988 4.0 5.0 5.0
2023 51.344825 48034.6020 948 9.0 8.0 8.0
7 2022 46.600406 44117.2090 953 6.0 6.0 6.0
2023 50.345047 49530.2960 990 10.0 7.0 5.0
8 2023 54.251672 54127.6185 993 2.0 3.0 4.0
2022 46.270479 42985.8100 936 8.0 8.0 7.0
9 2022 47.551170 48692.5280 1006 1.0 3.0 4.0
2023 51.946690 53197.1210 1021 8.0 4.0 2.0
10 2023 52.204931 26324.9065 496 6.0 9.0 9.0
2022 45.734077 23610.1010 519 9.0 10.0 10.0
In [ ]:
import plotly.graph_objects as go

# Reset the index
df_sorted_reset = df_sorted.reset_index()

# Create a color sequence similar to 'Pastel2'
color_sequence = ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae']

# Get the 'ID_Loja' with the best rank in 2023
best_rank_id_loja_2023 = df_sorted_reset[(df_sorted_reset['Year'] == 2023) & (df_sorted_reset['Rank_Ticket_Medio'] == df_sorted_reset['Rank_Ticket_Medio'].min())]['ID_Loja'].values[0]

# Create a bar plot
fig = go.Figure()

for i, year in enumerate(df_sorted_reset['Year'].unique()):
    df_year = df_sorted_reset[df_sorted_reset['Year'] == year]
    fig.add_trace(go.Bar(
        x=df_year['ID_Loja'],
        y=df_year['Ticket Médio'],
        name=str(year),
        text=df_year['Rank_Ticket_Medio'],
        legendgroup=str(year),
        marker_color=[color_sequence[i % len(color_sequence)] if id_loja != best_rank_id_loja_2023 or year != 2023 else '#ff0000' for id_loja in df_year['ID_Loja']],  # Highlight the best rank in 2023
        hovertemplate='ID_Loja: %{x}<br>Ticket Médio: %{y}<br>Year: '+str(year)+'<br>Rank: %{text}<extra></extra>',
    ))

# Add title and set barmode to 'group'
fig.update_layout(title_text='Ticket Médio by ID_Loja and Year', barmode='group')

# Show the plot
fig.show()
In [ ]:
df_grouped_unique = df_final.groupby(['ID_Loja', 'Year','Marca']).agg({'Ticket Médio': 'mean',
    'UnidadesVendidas': 'sum',
    'ValorTotal': 'sum'})
df_pivot = df_grouped_unique.reset_index().pivot_table(index=['ID_Loja', 'Marca'], columns='Year', values=['Ticket Médio', 'UnidadesVendidas', 'ValorTotal'])


df_sorted_2023 = df_sorted.loc[(slice(None), 2023), ['Rank_Ticket_Medio']]
df_sorted_2023_sorted = df_sorted_2023.sort_values(by='Rank_Ticket_Medio')
id_loja_list = df_sorted_2023_sorted.index.get_level_values('ID_Loja').tolist()


df_pivot_reindexed = df_pivot.reindex(id_loja_list, level='ID_Loja')
df_pivot_reindexed
Out[ ]:
Ticket Médio UnidadesVendidas ValorTotal
Year 2022 2023 2022 2023 2022 2023
ID_Loja Marca
5 AlfaX 48.298856 51.919556 392 281 19386.719 14665.9730
BetaY 30.550208 30.193652 280 322 8470.860 9722.6115
GammaZ 62.043514 78.319247 246 351 15311.181 27354.2895
8 AlfaX 48.455955 51.706533 336 267 16214.505 13774.6700
BetaY 30.425517 29.410358 346 345 10595.391 10161.7525
GammaZ 64.059239 78.407126 254 381 16175.914 30191.1960
2 AlfaX 46.985413 52.375821 373 282 17278.751 14766.2600
BetaY 30.038618 30.325560 376 330 11273.118 10116.9280
GammaZ 62.598226 75.406337 292 385 18114.327 29265.1525
1 AlfaX 48.757966 51.915592 201 161 9827.015 8351.0760
BetaY 30.313425 31.191597 183 173 5532.991 5313.5580
GammaZ 63.030129 78.433265 146 142 9573.360 11217.5915
4 AlfaX 49.902427 51.353214 423 327 21087.803 16852.0600
BetaY 30.297239 29.890853 364 359 11042.411 10803.6145
GammaZ 67.300108 80.058471 267 279 18014.982 22381.7630
10 AlfaX 48.031683 53.792261 185 169 8923.987 9121.3160
BetaY 29.750175 29.275407 195 159 5751.283 4638.9740
GammaZ 64.213881 74.007135 139 168 8934.831 12564.6165
3 AlfaX 50.642645 50.089595 433 325 21849.151 16237.2120
BetaY 29.973844 29.887072 354 371 10626.515 11242.5300
GammaZ 60.938252 76.703998 306 366 18594.990 27911.6390
9 AlfaX 50.239538 51.382169 380 315 19181.263 16290.0740
BetaY 29.728973 29.162800 304 345 8982.225 9900.8580
GammaZ 63.119262 73.818462 322 361 20529.040 27006.1890
6 AlfaX 48.937641 51.914289 371 277 18118.974 14485.0965
BetaY 30.660355 29.875186 361 374 11166.066 11194.9255
GammaZ 67.053894 75.614248 256 297 17120.690 22354.5800
7 AlfaX 49.349883 51.860462 370 296 18262.957 15475.5260
BetaY 30.708510 29.749969 346 364 10549.392 10923.2990
GammaZ 64.310491 71.384326 237 330 15304.860 23131.4710
In [ ]:
df_pivot_reindexed.info()
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 30 entries, (5, 'AlfaX') to (7, 'GammaZ')
Data columns (total 6 columns):
 #   Column                    Non-Null Count  Dtype  
---  ------                    --------------  -----  
 0   (Ticket Médio, 2022)      30 non-null     float64
 1   (Ticket Médio, 2023)      30 non-null     float64
 2   (UnidadesVendidas, 2022)  30 non-null     int64  
 3   (UnidadesVendidas, 2023)  30 non-null     int64  
 4   (ValorTotal, 2022)        30 non-null     float64
 5   (ValorTotal, 2023)        30 non-null     float64
dtypes: float64(4), int64(2)
memory usage: 2.0+ KB
In [ ]:
import matplotlib.pyplot as plt
import numpy as np

# Calculate the variation for each column
for col in ['Ticket Médio', 'ValorTotal', 'UnidadesVendidas']:
    df_pivot_reindexed[(col, 'Variação 2022-2023')] = ((df_pivot_reindexed[(col, 2023)] - df_pivot_reindexed[(col, 2022)]) / df_pivot_reindexed[(col, 2022)]) * 100

# Fill NaN values with 0
df_pivot_reindexed = df_pivot_reindexed.fillna(0)

# Reindex the columns
df_pivot_reindexed = df_pivot_reindexed.reindex([
    ('Ticket Médio', 2022),
    ('Ticket Médio', 2023),
    ('Ticket Médio', 'Variação 2022-2023'),
    ('UnidadesVendidas', 2022),
    ('UnidadesVendidas', 2023),
    ('UnidadesVendidas', 'Variação 2022-2023'),
    ('ValorTotal', 2022),
    ('ValorTotal', 2023),
    ('ValorTotal', 'Variação 2022-2023')
], axis=1)

# Define the figure size
fig, ax = plt.subplots(figsize=(15, 10))

# Add the table to the figure
table_data = df_pivot_reindexed.reset_index().round(2).values.tolist()
column_labels = df_pivot_reindexed.reset_index().columns.tolist()

# Create a color dictionary for each 'ID_Loja'
id_loja_colors = {id_loja: colors[i % len(colors)] for i, id_loja in enumerate(df_pivot_reindexed.index.get_level_values('ID_Loja').unique())}

# Create a color matrix based on 'ID_Loja'
cell_colors = [[id_loja_colors[row[0]] for _ in row] for row in table_data]

# Highlight the largest numbers in each column, skipping the first two columns
for i in range(2, len(table_data[0])):
    column_data = [row[i] for row in table_data]
    max_value = max(column_data)
    for j in range(len(table_data)):
        if table_data[j][i] == max_value:
            cell_colors[j][i] = (0, 0, 1, 0.5)

# Add the table to the figure
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc='center', loc='center', cellColours=cell_colors)

# Adjust the font size
table.auto_set_font_size(False)
table.set_fontsize(16)

# Increase the overall width and height of the table
table.scale(5, 4.5)

# Increase the font size
table.set_fontsize(25)

# Adjust the font size of the headers
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(20)

# Adjust the font size of 'ID_Loja' and 'Marca' columns
for key, cell in table.get_celld().items():
    if key[1] in [0, 1]:
        cell.set_fontsize(18)

# Hide the axes
ax.axis('off')

# Save the figure as .png
plt.savefig('df_pivot_reindexed_table.png')
No description has been provided for this image
In [ ]:
df_pivot_reindexed
Out[ ]:
Ticket Médio UnidadesVendidas ValorTotal
Year 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023
ID_Loja Marca
5 AlfaX 48.298856 51.919556 7.496451 392 281 -28.316327 19386.719 14665.9730 -24.350412
BetaY 30.550208 30.193652 -1.167113 280 322 15.000000 8470.860 9722.6115 14.777148
GammaZ 62.043514 78.319247 26.232770 246 351 42.682927 15311.181 27354.2895 78.655647
8 AlfaX 48.455955 51.706533 6.708313 336 267 -20.535714 16214.505 13774.6700 -15.047237
BetaY 30.425517 29.410358 -3.336537 346 345 -0.289017 10595.391 10161.7525 -4.092709
GammaZ 64.059239 78.407126 22.397842 254 381 50.000000 16175.914 30191.1960 86.642906
2 AlfaX 46.985413 52.375821 11.472514 373 282 -24.396783 17278.751 14766.2600 -14.540929
BetaY 30.038618 30.325560 0.955245 376 330 -12.234043 11273.118 10116.9280 -10.256169
GammaZ 62.598226 75.406337 20.460822 292 385 31.849315 18114.327 29265.1525 61.558045
1 AlfaX 48.757966 51.915592 6.476125 201 161 -19.900498 9827.015 8351.0760 -15.019200
BetaY 30.313425 31.191597 2.896976 183 173 -5.464481 5532.991 5313.5580 -3.965902
GammaZ 63.030129 78.433265 24.437736 146 142 -2.739726 9573.360 11217.5915 17.175072
4 AlfaX 49.902427 51.353214 2.907246 423 327 -22.695035 21087.803 16852.0600 -20.086222
BetaY 30.297239 29.890853 -1.341329 364 359 -1.373626 11042.411 10803.6145 -2.162540
GammaZ 67.300108 80.058471 18.957419 267 279 4.494382 18014.982 22381.7630 24.239719
10 AlfaX 48.031683 53.792261 11.993288 185 169 -8.648649 8923.987 9121.3160 2.211220
BetaY 29.750175 29.275407 -1.595851 195 159 -18.461538 5751.283 4638.9740 -19.340189
GammaZ 64.213881 74.007135 15.250992 139 168 20.863309 8934.831 12564.6165 40.625116
3 AlfaX 50.642645 50.089595 -1.092063 433 325 -24.942263 21849.151 16237.2120 -25.684929
BetaY 29.973844 29.887072 -0.289490 354 371 4.802260 10626.515 11242.5300 5.796962
GammaZ 60.938252 76.703998 25.871675 306 366 19.607843 18594.990 27911.6390 50.103006
9 AlfaX 50.239538 51.382169 2.274366 380 315 -17.105263 19181.263 16290.0740 -15.072986
BetaY 29.728973 29.162800 -1.904448 304 345 13.486842 8982.225 9900.8580 10.227232
GammaZ 63.119262 73.818462 16.950767 322 361 12.111801 20529.040 27006.1890 31.551154
6 AlfaX 48.937641 51.914289 6.082533 371 277 -25.336927 18118.974 14485.0965 -20.055647
BetaY 30.660355 29.875186 -2.560861 361 374 3.601108 11166.066 11194.9255 0.258457
GammaZ 67.053894 75.614248 12.766379 256 297 16.015625 17120.690 22354.5800 30.570555
7 AlfaX 49.349883 51.860462 5.087305 370 296 -20.000000 18262.957 15475.5260 -15.262758
BetaY 30.708510 29.749969 -3.121418 346 364 5.202312 10549.392 10923.2990 3.544346
GammaZ 64.310491 71.384326 10.999504 237 330 39.240506 15304.860 23131.4710 51.138076
In [ ]:
df_grouped_unique = df_final.groupby(['ID_Loja', 'Year','UF']).agg({'Ticket Médio': 'mean',
    'UnidadesVendidas': 'sum',
    'ValorTotal': 'sum'})
df_pivot = df_grouped_unique.reset_index().pivot_table(index=['ID_Loja', 'UF'], columns='Year', values=['Ticket Médio', 'UnidadesVendidas', 'ValorTotal'])


df_sorted_2023 = df_sorted.loc[(slice(None), 2023), ['Rank_Ticket_Medio']]
df_sorted_2023_sorted = df_sorted_2023.sort_values(by='Rank_Ticket_Medio')
id_loja_list = df_sorted_2023_sorted.index.get_level_values('ID_Loja').tolist()


df_pivot_reindexed = df_pivot.reindex(id_loja_list, level='ID_Loja')


import matplotlib.pyplot as plt
import numpy as np

# Calculate the variation for each column
for col in ['Ticket Médio', 'ValorTotal', 'UnidadesVendidas']:
    df_pivot_reindexed[(col, 'Variação 2022-2023')] = ((df_pivot_reindexed[(col, 2023)] - df_pivot_reindexed[(col, 2022)]) / df_pivot_reindexed[(col, 2022)]) * 100

# Fill NaN values with 0
df_pivot_reindexed = df_pivot_reindexed.fillna(0)

# Reindex the columns
df_pivot_reindexed = df_pivot_reindexed.reindex([
    ('Ticket Médio', 2022),
    ('Ticket Médio', 2023),
    ('Ticket Médio', 'Variação 2022-2023'),
    ('UnidadesVendidas', 2022),
    ('UnidadesVendidas', 2023),
    ('UnidadesVendidas', 'Variação 2022-2023'),
    ('ValorTotal', 2022),
    ('ValorTotal', 2023),
    ('ValorTotal', 'Variação 2022-2023')
], axis=1)

# Define the figure size
fig, ax = plt.subplots(figsize=(15, 10))

# Add the table to the figure
table_data = df_pivot_reindexed.reset_index().round(2).values.tolist()
column_labels = df_pivot_reindexed.reset_index().columns.tolist()

# Create a color dictionary for each 'ID_Loja'
id_loja_colors = {id_loja: colors[i % len(colors)] for i, id_loja in enumerate(df_pivot_reindexed.index.get_level_values('ID_Loja').unique())}

# Create a color matrix based on 'ID_Loja'
cell_colors = [[id_loja_colors[row[0]] for _ in row] for row in table_data]

# Highlight the largest numbers in each column, skipping the first two columns
for i in range(2, len(table_data[0])):
    column_data = [row[i] for row in table_data]
    max_value = max(column_data)
    for j in range(len(table_data)):
        if table_data[j][i] == max_value:
            cell_colors[j][i] = (0, 0, 1, 0.5)  # Change to semi-transparent blue

# Add the table to the figure
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc='center', loc='center', cellColours=cell_colors)

# Adjust the font size
table.auto_set_font_size(False)
table.set_fontsize(16)

# Increase the overall width and height of the table
table.scale(5, 4.5)

# Increase the font size
table.set_fontsize(25)

# Adjust the font size of the headers
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(20)

# Adjust the font size of 'ID_Loja' and 'UF' columns
for key, cell in table.get_celld().items():
    if key[1] in [0, 1]:
        cell.set_fontsize(18)

# Hide the axes
ax.axis('off')

# Save the figure as .png
plt.savefig('df_pivot_reindexed_table.png')
No description has been provided for this image
In [ ]:
df_pivot_reindexed
Out[ ]:
Ticket Médio UnidadesVendidas ValorTotal
Year 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023
ID_Loja UF
5 SP 46.310672 54.538466 17.766518 918 954 3.921569 43168.760 51742.8740 19.861849
8 RS 46.270479 54.251672 17.248997 936 993 6.089744 42985.810 54127.6185 25.919736
2 MG 45.367873 54.171854 19.405762 1041 997 -4.226705 46666.196 54148.3405 16.033328
1 AM 47.247530 53.186719 12.570369 530 476 -10.188679 24933.366 24882.2255 -0.205109
4 SP 47.407694 52.388917 10.507204 1054 965 -8.444023 50145.196 50037.4375 -0.214893
10 BH 45.734077 52.204931 14.148867 519 496 -4.431599 23610.101 26324.9065 11.498492
3 SP 46.916761 52.052152 10.945747 1093 1062 -2.836231 51070.656 55391.3810 8.460289
9 BH 47.551170 51.946690 9.243767 1006 1021 1.491054 48692.528 53197.1210 9.251097
6 SP 47.123065 51.344825 8.959008 988 948 -4.048583 46405.730 48034.6020 3.510067
7 RS 46.600406 50.345047 8.035641 953 990 3.882476 44117.209 49530.2960 12.269786
In [ ]:
df_grouped_unique = df_final.groupby(['ID_Loja', 'Year','ClasseSocial']).agg({'Ticket Médio': 'mean',
    'UnidadesVendidas': 'sum',
    'ValorTotal': 'sum'})
df_pivot = df_grouped_unique.reset_index().pivot_table(index=['ID_Loja', 'ClasseSocial'], columns='Year', values=['Ticket Médio', 'UnidadesVendidas', 'ValorTotal'])


df_sorted_2023 = df_sorted.loc[(slice(None), 2023), ['Rank_Ticket_Medio']]
df_sorted_2023_sorted = df_sorted_2023.sort_values(by='Rank_Ticket_Medio')
id_loja_list = df_sorted_2023_sorted.index.get_level_values('ID_Loja').tolist()


df_pivot_reindexed = df_pivot.reindex(id_loja_list, level='ID_Loja')


import matplotlib.pyplot as plt
import numpy as np

# Calculate the variation for each column
for col in ['Ticket Médio', 'ValorTotal', 'UnidadesVendidas']:
    df_pivot_reindexed[(col, 'Variação 2022-2023')] = ((df_pivot_reindexed[(col, 2023)] - df_pivot_reindexed[(col, 2022)]) / df_pivot_reindexed[(col, 2022)]) * 100

# Fill NaN values with 0
df_pivot_reindexed = df_pivot_reindexed.fillna(0)

# Reindex the columns
df_pivot_reindexed = df_pivot_reindexed.reindex([
    ('Ticket Médio', 2022),
    ('Ticket Médio', 2023),
    ('Ticket Médio', 'Variação 2022-2023'),
    ('UnidadesVendidas', 2022),
    ('UnidadesVendidas', 2023),
    ('UnidadesVendidas', 'Variação 2022-2023'),
    ('ValorTotal', 2022),
    ('ValorTotal', 2023),
    ('ValorTotal', 'Variação 2022-2023')
], axis=1)

# Define the figure size
fig, ax = plt.subplots(figsize=(15, 10))

# Add the table to the figure
table_data = df_pivot_reindexed.reset_index().round(2).values.tolist()
column_labels = df_pivot_reindexed.reset_index().columns.tolist()

# Create a color dictionary for each 'ID_Loja'
id_loja_colors = {id_loja: colors[i % len(colors)] for i, id_loja in enumerate(df_pivot_reindexed.index.get_level_values('ID_Loja').unique())}

# Create a color matrix based on 'ID_Loja'
cell_colors = [[id_loja_colors[row[0]] for _ in row] for row in table_data]

# Highlight the largest numbers in each column, skipping the first two columns
for i in range(2, len(table_data[0])):
    column_data = [row[i] for row in table_data]
    max_value = max(column_data)
    for j in range(len(table_data)):
        if table_data[j][i] == max_value:
            cell_colors[j][i] = (0, 0, 1, 0.5)  # Change to semi-transparent blue

# Add the table to the figure
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc='center', loc='center', cellColours=cell_colors)

# Adjust the font size
table.auto_set_font_size(False)
table.set_fontsize(16)

# Increase the overall width and height of the table
table.scale(5, 4.5)

# Increase the font size
table.set_fontsize(25)

# Adjust the font size of the headers
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(20)

# Adjust the font size of 'ID_Loja' and 'ClasseSocial' columns
for key, cell in table.get_celld().items():
    if key[1] in [0, 1]:
        cell.set_fontsize(18)

# Hide the axes
ax.axis('off')

# Save the figure as .png
plt.savefig('df_pivot_reindexed_table.png')
No description has been provided for this image
In [ ]:
df_pivot_reindexed
Out[ ]:
Ticket Médio UnidadesVendidas ValorTotal
Year 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023
ID_Loja ClasseSocial
5 A 43.633587 50.513952 15.768507 113 91 -19.469027 5006.480 4671.1005 -6.698908
B 47.703415 61.282756 28.466182 120 107 -10.833333 5830.626 6763.9360 16.007029
C 46.856150 52.489905 12.023512 472 566 19.915254 22400.148 29599.6090 32.140239
D 46.060351 59.643773 29.490487 128 101 -21.093750 5951.142 5776.5550 -2.933672
E 44.972529 57.037849 26.828198 85 89 4.705882 3980.364 4931.6735 23.900063
8 A 45.366220 48.022214 5.854564 116 106 -8.620690 5411.663 5257.9990 -2.839497
B 42.024935 57.257794 36.247193 103 134 30.097087 4113.388 7506.8795 82.498697
C 46.679818 56.114864 20.212259 502 508 1.195219 23228.477 28377.8860 22.168518
D 47.285102 50.397712 6.582645 132 127 -3.787879 6210.303 6662.7480 7.285393
E 48.677282 53.289340 9.474764 83 118 42.168675 4021.979 6322.1060 57.188936
2 A 45.805882 54.981678 20.031915 123 146 18.699187 5470.397 7755.8080 41.777791
B 45.470885 56.471817 24.193355 121 102 -15.702479 5402.401 5824.7435 7.817681
C 45.300776 55.169948 21.785877 553 543 -1.808318 24906.401 30026.7180 20.558237
D 43.442446 47.226607 8.710746 145 125 -13.793103 6257.970 5881.3750 -6.017846
E 48.004140 57.294176 19.352573 99 81 -18.181818 4629.027 4659.6960 0.662537
1 A 38.328034 55.649731 45.193281 63 63 0.000000 2457.376 3578.8290 45.636199
B 55.390143 60.329239 8.916923 52 54 3.846154 2766.688 3165.0685 14.399184
C 47.796315 50.874248 6.439685 296 248 -16.216216 14077.281 12347.9070 -12.284858
D 47.475786 48.296870 1.729479 65 51 -21.538462 3076.156 2331.6560 -24.202284
E 47.699227 58.669417 22.998673 54 60 11.111111 2555.865 3458.7650 35.326592
4 A 48.360951 51.176568 5.822086 104 94 -9.615385 5172.982 4706.2175 -9.023122
B 38.871359 51.172567 31.645941 169 132 -21.893491 6589.130 6686.5505 1.478503
C 51.267690 52.204378 1.827054 542 529 -2.398524 27918.637 27572.9230 -1.238291
D 42.143313 53.137152 26.086794 134 124 -7.462687 5654.283 6355.4870 12.401289
E 46.213349 55.357314 19.786416 105 86 -18.095238 4810.164 4716.2595 -1.952210
10 A 45.956900 60.490079 31.623497 69 44 -36.231884 3124.128 2644.0645 -15.366320
B 41.964043 55.216030 31.579385 63 75 19.047619 2717.578 4250.5255 56.408593
C 46.454500 49.226461 5.967046 257 256 -0.389105 11927.681 12925.2055 8.363105
D 43.996767 52.505333 19.339073 69 60 -13.043478 2989.715 3275.9135 9.572769
E 47.713231 53.636536 12.414387 61 61 0.000000 2850.999 3229.1975 13.265473
3 A 43.044333 53.093768 23.346708 110 101 -8.181818 4840.917 5498.7505 13.589027
B 48.175691 50.550000 4.928438 132 123 -6.818182 6492.908 6404.7700 -1.357450
C 47.251256 52.895807 11.945823 592 596 0.675676 27451.785 31492.2660 14.718464
D 46.581464 52.209549 12.082241 153 138 -9.803922 7131.296 6891.6835 -3.360013
E 48.269186 47.869289 -0.828473 106 104 -1.886792 5153.750 5103.9110 -0.967043
9 A 50.094565 50.053478 -0.082020 103 161 56.310680 5320.793 8021.8975 50.765074
B 50.480660 49.041503 -2.850908 124 117 -5.645161 6288.372 5788.5460 -7.948417
C 47.661374 52.837951 10.861159 493 557 12.981744 23918.171 29672.7510 24.059448
D 41.890200 54.760292 30.723395 178 98 -44.943820 7533.657 5356.6405 -28.897208
E 51.021244 49.476953 -3.026762 108 88 -18.518519 5631.535 4357.2860 -22.627028
6 A 47.713976 53.590000 12.315100 98 105 7.142857 4773.039 5659.9500 18.581683
B 41.151022 53.120510 29.086735 111 111 0.000000 4514.707 6109.9190 35.333677
C 46.522709 50.868942 9.342177 532 537 0.939850 24696.211 26470.4515 7.184262
D 49.172018 50.008458 1.701049 130 109 -16.153846 6464.527 5542.3765 -14.264779
E 52.753388 51.490182 -2.394549 117 86 -26.495726 5957.246 4251.9050 -28.626332
7 A 46.390193 54.717536 17.950655 125 130 4.000000 5758.974 7558.2235 31.242536
B 45.858686 53.624047 16.933240 84 124 47.619048 3959.771 6562.9160 65.739786
C 45.485690 49.590752 9.024954 461 507 9.978308 20722.251 24746.5790 19.420323
D 49.183036 50.082790 1.829399 140 120 -14.285714 6853.227 5915.0520 -13.689536
E 48.662517 45.262278 -6.987389 143 109 -23.776224 6822.986 4747.5255 -30.418654
In [ ]:
df_grouped_unique = df_final.groupby(['ID_Loja', 'Year','Genero']).agg({'Ticket Médio': 'mean',
    'UnidadesVendidas': 'sum',
    'ValorTotal': 'sum'})
df_pivot = df_grouped_unique.reset_index().pivot_table(index=['ID_Loja', 'Genero'], columns='Year', values=['Ticket Médio', 'UnidadesVendidas', 'ValorTotal'])


df_sorted_2023 = df_sorted.loc[(slice(None), 2023), ['Rank_Ticket_Medio']]
df_sorted_2023_sorted = df_sorted_2023.sort_values(by='Rank_Ticket_Medio')
id_loja_list = df_sorted_2023_sorted.index.get_level_values('ID_Loja').tolist()


df_pivot_reindexed = df_pivot.reindex(id_loja_list, level='ID_Loja')


import matplotlib.pyplot as plt
import numpy as np

# Calculate the variation for each column
for col in ['Ticket Médio', 'ValorTotal', 'UnidadesVendidas']:
    df_pivot_reindexed[(col, 'Variação 2022-2023')] = ((df_pivot_reindexed[(col, 2023)] - df_pivot_reindexed[(col, 2022)]) / df_pivot_reindexed[(col, 2022)]) * 100

# Fill NaN values with 0
df_pivot_reindexed = df_pivot_reindexed.fillna(0)

# Reindex the columns
df_pivot_reindexed = df_pivot_reindexed.reindex([
    ('Ticket Médio', 2022),
    ('Ticket Médio', 2023),
    ('Ticket Médio', 'Variação 2022-2023'),
    ('UnidadesVendidas', 2022),
    ('UnidadesVendidas', 2023),
    ('UnidadesVendidas', 'Variação 2022-2023'),
    ('ValorTotal', 2022),
    ('ValorTotal', 2023),
    ('ValorTotal', 'Variação 2022-2023')
], axis=1)

# Define the figure size
fig, ax = plt.subplots(figsize=(15, 10))

# Add the table to the figure
table_data = df_pivot_reindexed.reset_index().round(2).values.tolist()
column_labels = df_pivot_reindexed.reset_index().columns.tolist()

# Create a color dictionary for each 'ID_Loja'
id_loja_colors = {id_loja: colors[i % len(colors)] for i, id_loja in enumerate(df_pivot_reindexed.index.get_level_values('ID_Loja').unique())}

# Create a color matrix based on 'ID_Loja'
cell_colors = [[id_loja_colors[row[0]] for _ in row] for row in table_data]

# Highlight the largest numbers in each column, skipping the first two columns
for i in range(2, len(table_data[0])):
    column_data = [row[i] for row in table_data]
    max_value = max(column_data)
    for j in range(len(table_data)):
        if table_data[j][i] == max_value:
            cell_colors[j][i] = (0, 0, 1, 0.5)  # Change to semi-transparent blue

# Add the table to the figure
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc='center', loc='center', cellColours=cell_colors)

# Adjust the font size
table.auto_set_font_size(False)
table.set_fontsize(16)

# Increase the overall width and height of the table
table.scale(5, 4.5)

# Increase the font size
table.set_fontsize(25)

# Adjust the font size of the headers
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(20)

# Adjust the font size of 'ID_Loja' and 'Genero' columns
for key, cell in table.get_celld().items():
    if key[1] in [0, 1]:
        cell.set_fontsize(18)

# Hide the axes
ax.axis('off')

# Save the figure as .png
plt.savefig('df_pivot_reindexed_table.png')
No description has been provided for this image
In [ ]:
df_pivot_reindexed
Out[ ]:
Ticket Médio UnidadesVendidas ValorTotal
Year 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023
ID_Loja Genero
5 Feminino 45.539566 55.894260 22.737795 592 562 -5.067568 27367.979 31106.5825 13.660503
Masculino 47.951212 50.841120 6.026767 251 311 23.904382 12121.324 15714.0910 29.640054
8 Feminino 45.897440 56.201730 22.450687 558 611 9.498208 25342.124 34942.9165 37.884719
Masculino 47.775171 51.688679 8.191510 287 296 3.135889 13660.776 15285.0985 11.890412
2 Feminino 45.627122 54.857028 20.228989 661 603 -8.774584 30017.320 33531.0435 11.705654
Masculino 44.711723 52.933698 18.388857 310 324 4.516129 13562.954 16887.9955 24.515614
1 Feminino 48.384333 52.648310 8.812722 318 267 -16.037736 15025.457 13966.2710 -7.049276
Masculino 45.425595 54.294032 19.522995 178 187 5.056180 8226.845 9800.5200 19.128536
4 Feminino 47.015232 52.051972 10.712994 644 599 -6.987578 30500.457 30990.5095 1.606705
Masculino 46.716348 53.906543 15.391177 330 285 -13.636364 15484.931 15064.9230 -2.712366
10 Feminino 46.481854 51.166258 10.077920 348 328 -5.747126 16020.778 17154.4015 7.075958
Masculino 43.651072 56.033557 28.366964 153 137 -10.457516 6667.503 7721.8120 15.812651
3 Feminino 47.302661 50.660496 7.098617 717 633 -11.715481 33418.740 32278.5130 -3.411939
Masculino 47.187879 54.195620 14.850724 314 346 10.191083 15113.521 18474.2860 22.236810
9 Feminino 45.883656 52.011682 13.355575 634 598 -5.678233 29525.777 31318.9375 6.073203
Masculino 50.839129 50.444481 -0.776270 311 331 6.430868 15928.154 16747.0445 5.141151
6 Feminino 48.268811 51.267747 6.212991 662 589 -11.027190 31679.526 30370.8005 -4.131140
Masculino 44.645858 51.669102 15.731010 279 297 6.451613 12465.870 14756.3185 18.373756
7 Feminino 46.335446 49.605229 7.056764 613 587 -4.241436 28109.750 28853.9740 2.647565
Masculino 49.965800 51.156508 2.383046 276 316 14.492754 13755.886 16127.1920 17.238482
In [ ]:
df_grouped_unique = df_final.groupby(['ID_Loja', 'Year','FaixaIdade']).agg({'Ticket Médio': 'mean',
    'UnidadesVendidas': 'sum',
    'ValorTotal': 'sum'})
df_pivot = df_grouped_unique.reset_index().pivot_table(index=['ID_Loja', 'FaixaIdade'], columns='Year', values=['Ticket Médio', 'UnidadesVendidas', 'ValorTotal'])


df_sorted_2023 = df_sorted.loc[(slice(None), 2023), ['Rank_Ticket_Medio']]
df_sorted_2023_sorted = df_sorted_2023.sort_values(by='Rank_Ticket_Medio')
id_loja_list = df_sorted_2023_sorted.index.get_level_values('ID_Loja').tolist()


df_pivot_reindexed = df_pivot.reindex(id_loja_list, level='ID_Loja')


import matplotlib.pyplot as plt
import numpy as np

# Calculate the variation for each column
for col in ['Ticket Médio', 'ValorTotal', 'UnidadesVendidas']:
    df_pivot_reindexed[(col, 'Variação 2022-2023')] = ((df_pivot_reindexed[(col, 2023)] - df_pivot_reindexed[(col, 2022)]) / df_pivot_reindexed[(col, 2022)]) * 100

# Fill NaN values with 0
df_pivot_reindexed = df_pivot_reindexed.fillna(0)

# Reindex the columns
df_pivot_reindexed = df_pivot_reindexed.reindex([
    ('Ticket Médio', 2022),
    ('Ticket Médio', 2023),
    ('Ticket Médio', 'Variação 2022-2023'),
    ('UnidadesVendidas', 2022),
    ('UnidadesVendidas', 2023),
    ('UnidadesVendidas', 'Variação 2022-2023'),
    ('ValorTotal', 2022),
    ('ValorTotal', 2023),
    ('ValorTotal', 'Variação 2022-2023')
], axis=1)

# Define the figure size
fig, ax = plt.subplots(figsize=(15, 10))

# Add the table to the figure
table_data = df_pivot_reindexed.reset_index().round(2).values.tolist()
column_labels = df_pivot_reindexed.reset_index().columns.tolist()

# Create a color dictionary for each 'ID_Loja'
id_loja_colors = {id_loja: colors[i % len(colors)] for i, id_loja in enumerate(df_pivot_reindexed.index.get_level_values('ID_Loja').unique())}

# Create a color matrix based on 'ID_Loja'
cell_colors = [[id_loja_colors[row[0]] for _ in row] for row in table_data]

# Highlight the largest numbers in each column, skipping the first two columns
for i in range(2, len(table_data[0])):
    column_data = [row[i] for row in table_data]
    max_value = max(column_data)
    for j in range(len(table_data)):
        if table_data[j][i] == max_value:
            cell_colors[j][i] = (0, 0, 1, 0.5)  # Change to semi-transparent blue

# Add the table to the figure
table = ax.table(cellText=table_data, colLabels=column_labels, cellLoc='center', loc='center', cellColours=cell_colors)

# Adjust the font size
table.auto_set_font_size(False)
table.set_fontsize(16)

# Increase the overall width and height of the table
table.scale(5, 4.5)

# Increase the font size
table.set_fontsize(25)

# Adjust the font size of the headers
for key, cell in table.get_celld().items():
    if key[0] == 0:
        cell.set_fontsize(20)

# Adjust the font size of 'ID_Loja' and 'FaixaIdade' columns
for key, cell in table.get_celld().items():
    if key[1] in [0, 1]:
        cell.set_fontsize(18)

# Hide the axes
ax.axis('off')

# Save the figure as .png
plt.savefig('df_pivot_reindexed_table.png')
No description has been provided for this image
In [ ]:
df_pivot_reindexed
Out[ ]:
Ticket Médio UnidadesVendidas ValorTotal
Year 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023 2022 2023 Variação 2022-2023
ID_Loja FaixaIdade
5 18-25 46.519355 57.339261 23.258934 63 105 66.666667 2856.791 5946.3335 108.147306
25-35 48.030908 53.893296 12.205449 499 503 0.801603 24427.073 27292.1660 11.729170
35-45 43.145016 54.849961 27.129308 291 273 -6.185567 12777.542 14742.7000 15.379781
45+ 47.403897 53.671297 13.221277 65 73 12.307692 3107.354 3761.6745 21.057160
8 18-25 50.412864 51.005483 1.175533 95 101 6.315789 4563.060 5229.9835 14.615707
25-35 44.943194 55.649665 23.822231 428 561 31.074766 18870.574 31577.9935 67.339867
35-45 44.075718 52.217285 18.471775 325 244 -24.923077 14615.824 12747.6765 -12.781678
45+ 56.710386 54.979237 -3.052613 88 87 -1.136364 4936.352 4571.9650 -7.381706
2 18-25 43.427512 53.043762 22.143222 90 104 15.555556 4108.327 5417.9790 31.877988
25-35 45.751605 54.284989 18.651550 531 520 -2.071563 23892.786 28834.0480 20.680979
35-45 45.071014 53.102765 17.820214 326 287 -11.963190 14458.797 15003.6045 3.768000
45+ 46.336659 58.578459 26.419257 94 86 -8.510638 4206.286 4892.7090 16.318981
1 18-25 50.300414 49.872516 -0.850684 68 64 -5.882353 3596.322 3094.0760 -13.965546
25-35 46.861571 54.143553 15.539345 248 242 -2.419355 11669.754 12926.2265 10.766915
35-45 46.145070 52.670856 14.141891 172 131 -23.837209 7676.100 6797.5050 -11.445851
45+ 49.079111 55.065125 12.196663 42 39 -7.142857 1991.190 2064.4180 3.677600
4 18-25 49.536206 51.773865 4.517218 148 88 -40.540541 7338.145 4696.1305 -36.003847
25-35 48.616369 52.651894 8.300754 469 506 7.889126 22593.361 26210.1525 16.008205
35-45 45.704853 51.327400 12.301860 330 288 -12.727273 15418.353 14706.9895 -4.613745
45+ 44.390085 55.438564 24.889519 107 83 -22.429907 4795.337 4424.1650 -7.740269
10 18-25 41.463533 57.821500 39.451454 67 56 -16.417910 2654.144 3309.9565 24.709002
25-35 47.092036 50.916405 8.121052 257 275 7.003891 11895.082 14405.0880 21.101208
35-45 44.926485 51.523433 14.683874 154 129 -16.233766 7039.275 6632.2220 -5.782598
45+ 47.870200 55.677500 16.309311 41 36 -12.195122 2021.600 1977.6400 -2.174515
3 18-25 42.551065 49.617083 16.605972 111 125 12.612613 4681.709 5868.8990 25.358048
25-35 47.470016 51.411488 8.303078 591 483 -18.274112 27894.995 25607.4035 -8.200724
35-45 45.204813 53.274137 17.850587 292 367 25.684932 13187.324 19488.0495 47.778651
45+ 53.444964 53.896359 0.844597 99 87 -12.121212 5306.628 4427.0290 -16.575479
9 18-25 44.770608 57.497569 28.427045 121 104 -14.049587 5318.621 6314.9830 18.733465
25-35 49.064563 51.504556 4.973026 491 510 3.869654 24967.758 26256.4540 5.161441
35-45 46.265015 52.206223 12.841685 286 308 7.692308 13287.401 15879.9680 19.511468
45+ 47.243327 47.462849 0.464664 108 99 -8.333333 5118.748 4745.7160 -7.287563
6 18-25 46.073195 46.744362 1.456741 95 136 43.157895 4238.081 6166.8990 45.511589
25-35 48.071274 52.582447 9.384344 479 440 -8.141962 22890.473 22885.4845 -0.021793
35-45 46.093468 50.354217 9.243717 297 297 0.000000 13795.504 14890.4555 7.937017
45+ 46.464254 56.447318 21.485473 117 75 -35.897436 5481.672 4091.7630 -25.355567
7 18-25 39.562552 52.898606 33.708783 142 114 -19.718310 5643.800 6026.8135 6.786447
25-35 46.322194 50.211995 8.397273 471 512 8.704883 21739.169 25503.7110 17.316862
35-45 49.155923 50.217441 2.159490 271 294 8.487085 12960.921 14712.4170 13.513669
45+ 52.547250 48.152167 -8.364060 69 70 1.449275 3773.319 3287.3545 -12.878967
Quinta parte da análise:¶
  • Teste
nesta quinta parte da análise é possível verificar que:¶

O valor de p é 0,185 ou 18,5%. Um valor de p menor que 0,05 geralmente é considerado evidência forte o suficiente para rejeitar a hipótese nula e aceitar a hipótese alternativa.

  • H0 (Hipótese nula): O teste não rejeita a hipótese nula pois não há associação significativa entre "Grupo" e "Comprou". Em outras palavras, a taxa de compra é praticamente a mesma para os grupos 'CONTROLE' e 'TESTE'.

  • H1 (Hipótese alternativa): O Teste rejeita hipótese alternativa que seria uma associação significativa entre "Grupo" e "Comprou".

Portanto não houve diferença significativa entre o Modelo ANTIGO e NOVO de disparo de e-mails.

Em testes de hipóteses, temos duas hipóteses principais:

  • H0 (Hipótese nula): Esta é a hipótese que assumimos ser verdadeira antes de coletar e analisar os dados. No seu caso, a hipótese nula é que não há associação significativa entre "Grupo" e "Comprou". Em outras palavras, a taxa de compra é a mesma para os grupos 'CONTROLE' e 'TESTE'.

  • H1 (Hipótese alternativa): Esta é a hipótese que queremos testar contra a hipótese nula. No seu caso, a hipótese alternativa é que há uma associação significativa entre "Grupo" e "Comprou". Ou seja, a taxa de compra é diferente para os grupos 'CONTROLE' e 'TESTE'.

O valor de p é a probabilidade de obter os resultados que você obteve (ou resultados mais extremos) se a hipótese nula for verdadeira. Um valor de p menor que 0,05 geralmente é considerado evidência forte o suficiente para rejeitar a hipótese nula e aceitar a hipótese alternativa.

No seu caso, o valor de p é 0,185, que é maior que 0,05. Isso significa que, se a hipótese nula for verdadeira (ou seja, se não houver associação significativa entre "Grupo" e "Comprou"), há uma probabilidade de 18,5% de obter os resultados que você obteve (ou resultados mais extremos). Portanto, você não rejeita a hipótese nula e conclui que não tem evidências suficientes para afirmar que há uma associação significativa entre "Grupo" e "Comprou".

Claro, vamos detalhar um pouco mais.

O valor de p, ou valor-p, é uma medida usada em estatística para ajudar a decidir se os resultados de um teste são significativos ou não. Especificamente, o valor-p é a probabilidade de obter um resultado tão extremo quanto o observado, assumindo que a hipótese nula é verdadeira.

No seu caso, o valor de p é 0,185, ou 18,5%. Isso significa que, se a hipótese nula for verdadeira (ou seja, se não houver diferença real na taxa de compra entre os grupos 'CONTROLE' e 'TESTE'), você ainda esperaria ver uma diferença tão grande quanto a que você observou (ou maior) em 18,5% das vezes que você repetisse o experimento.

Em outras palavras, mesmo que não haja diferença real, você veria uma diferença como essa (ou maior) puramente por acaso em cerca de 18,5% das vezes.

Como esse valor de p é maior que o limite comum de significância de 0,05, você não rejeita a hipótese nula. Isso significa que você não tem evidências suficientes para concluir que há uma diferença significativa na taxa de compra entre os grupos 'CONTROLE' e 'TESTE'.

In [ ]:
import openpyxl
import pandas as pd

# arquivo
wb = openpyxl.load_workbook('Exercicio_Python_CRM .xlsx', read_only=True)

# aba de Cliente
ws = wb['Cliente']

# tamanho do chunk para leitura de bases grandes
chunk_size = 100000
chunks = []

# cabeçalho (nomes das colunas) da primeira linha
header = [cell.value for cell in ws[1]]

# dados em chunks para bases com milhões de linhas
for i in range(2, ws.max_row, chunk_size):  # Comecça de 2 porque a primeira linha é o cabeçalho
    rows = ws[i:i + chunk_size]
    data = [[cell.value for cell in row] for row in rows]
    df = pd.DataFrame(data, columns=header)  # Usando o cabeçalho como nomes das colunas
    chunks.append(df)

# Concatenando os chunks em um único DataFrame
df_c = pd.concat(chunks, axis=0)

# Para cada coluna no DataFrame
for col in df_c.columns:
    # Se o tipo de dados da coluna é object (string)
    if pd.api.types.is_object_dtype(df_c[col]):
        # Remova os espaços em branco no início e no final
        df_c[col] = df_c[col].str.strip()
In [ ]:
import openpyxl
import pandas as pd

# arquivo
wb = openpyxl.load_workbook('Exercicio_Python_CRM .xlsx', read_only=True)

# aba de Teste
ws = wb['Teste']

# tamanho do chunk para leitura de bases grandes
chunk_size = 100000
chunks = []

# cabeçalho (nomes das colunas) da primeira linha
header = [cell.value for cell in ws[1]]

# dados em chunks para bases com milhões de linhas
for i in range(2, ws.max_row, chunk_size):  # Comecça de 2 porque a primeira linha é o cabeçalho
    rows = ws[i:i + chunk_size]
    data = [[cell.value for cell in row] for row in rows]
    df = pd.DataFrame(data, columns=header)  # Usando o cabeçalho como nomes das colunas
    chunks.append(df)

# Concatenando os chunks em um único DataFrame
df_tst = pd.concat(chunks, axis=0)

# Para cada coluna no DataFrame
for col in df_tst.columns:
    # Se o tipo de dados da coluna é object (string)
    if pd.api.types.is_object_dtype(df_tst[col]):
        # Remova os espaços em branco no início e no final
        df_tst[col] = df_tst[col].str.strip()
In [ ]:
df_c.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 8 columns):
 #   Column        Non-Null Count  Dtype 
---  ------        --------------  ----- 
 0   CustomerID    100 non-null    int64 
 1   Genero        93 non-null     object
 2   FaixaIdade    100 non-null    object
 3   ClasseSocial  100 non-null    object
 4   None          0 non-null      object
 5   None          0 non-null      object
 6   None          0 non-null      object
 7   None          0 non-null      object
dtypes: int64(1), object(7)
memory usage: 6.4+ KB
In [ ]:
df_c = df_c.dropna(axis=1, how='all')
In [ ]:
df_c[df_c['Genero'].isnull()]
Out[ ]:
CustomerID Genero FaixaIdade ClasseSocial
14 90014 None 25-35 D
18 90018 None 25-35 C
52 90052 None 25-35 C
53 90053 None 35-45 C
73 90073 None 35-45 A
80 90080 None 25-35 E
98 90098 None 25-35 C
In [ ]:
for col in df_c.columns:
    print(f'Column: {col}')
    print(df_c[col].value_counts(dropna=False))
Column: CustomerID
90000    1
90063    1
90073    1
90072    1
90071    1
        ..
90030    1
90029    1
90028    1
90027    1
90099    1
Name: CustomerID, Length: 100, dtype: int64
Column: Genero
Feminino     64
Masculino    29
None          7
Name: Genero, dtype: int64
Column: FaixaIdade
25-35    50
35-45    30
18-25    11
45+       9
Name: FaixaIdade, dtype: int64
Column: ClasseSocial
C    52
D    15
B    12
A    11
E    10
Name: ClasseSocial, dtype: int64
In [ ]:
df_tst.head(10)
Out[ ]:
CustomerID Grupo Enviado Recebido Aberto Sessao Comprou
0 90000 TESTE 1 1 1 1 1
1 90001 TESTE 1 1 0 0 0
2 90002 CONTROLE 1 1 0 0 0
3 90003 TESTE 1 1 1 1 1
4 90004 TESTE 1 1 1 1 1
5 90005 TESTE 1 1 1 1 0
6 90006 TESTE 1 1 0 0 0
7 90007 CONTROLE 1 1 1 1 1
8 90008 TESTE 1 1 1 1 1
9 90009 TESTE 1 1 1 1 1
In [ ]:
non_conforming_rows = df_tst.loc[
    ((df_tst['Enviado'] == 0) & (df_tst['Aberto'] != 0)) |
    ((df_tst['Enviado'] == 0) & (df_tst['Sessao'] != 0)) |
    ((df_tst['Recebido'] == 0) & (df_tst['Aberto'] != 0)) |
    ((df_tst['Aberto'] == 0) & (df_tst['Sessao'] != 0))
]
In [ ]:
non_conforming_rows
Out[ ]:
CustomerID Grupo Enviado Recebido Aberto Sessao Comprou
89 90089 CONTROLE 0 1 1 1 0
93 90093 TESTE 0 1 1 1 1
In [ ]:
df_tst = df_tst.drop(non_conforming_rows.index)
In [ ]:
df_tst.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 98 entries, 0 to 99
Data columns (total 7 columns):
 #   Column      Non-Null Count  Dtype 
---  ------      --------------  ----- 
 0   CustomerID  98 non-null     int64 
 1   Grupo       98 non-null     object
 2   Enviado     98 non-null     int64 
 3   Recebido    98 non-null     int64 
 4   Aberto      98 non-null     int64 
 5   Sessao      98 non-null     int64 
 6   Comprou     98 non-null     int64 
dtypes: int64(6), object(1)
memory usage: 6.1+ KB
In [ ]:
df_merged = df_tst.merge(df_c, on='CustomerID', how='left')
In [ ]:
df_merged
Out[ ]:
CustomerID Grupo Enviado Recebido Aberto Sessao Comprou Genero FaixaIdade ClasseSocial
0 90000 TESTE 1 1 1 1 1 Feminino 35-45 C
1 90001 TESTE 1 1 0 0 0 Feminino 45+ D
2 90002 CONTROLE 1 1 0 0 0 Feminino 18-25 C
3 90003 TESTE 1 1 1 1 1 Feminino 45+ C
4 90004 TESTE 1 1 1 1 1 Feminino 35-45 C
... ... ... ... ... ... ... ... ... ... ...
93 90095 TESTE 1 1 0 0 0 Masculino 18-25 C
94 90096 CONTROLE 1 1 1 1 1 Masculino 18-25 A
95 90097 CONTROLE 1 1 0 0 0 Masculino 45+ C
96 90098 TESTE 1 1 1 1 1 None 25-35 C
97 90099 CONTROLE 1 1 1 1 1 Feminino 25-35 E

98 rows × 10 columns

In [ ]:
# Group by 'Grupo' and calculate the mean of 'Comprou'
conversion_rate = df_merged.groupby('Grupo')['Comprou'].mean()

conversion_rate
Out[ ]:
Grupo
CONTROLE    0.584906
TESTE       0.733333
Name: Comprou, dtype: float64
In [ ]:
# Reset the index of the conversion_rate Series to convert it into a DataFrame
cr = conversion_rate.reset_index()

# Rename the columns
cr.columns = ['Grupo', 'conversion_rate']
cr
Out[ ]:
Grupo conversion_rate
0 CONTROLE 0.584906
1 TESTE 0.733333
In [ ]:
# Group by 'Grupo' and calculate the mean of 'Aberto'
opening_rate = df_merged.groupby('Grupo')['Aberto'].mean()

print(opening_rate)
Grupo
CONTROLE    0.867925
TESTE       0.911111
Name: Aberto, dtype: float64
In [ ]:
o_r = opening_rate.reset_index()

# Rename the columns
o_r.columns = ['Grupo', 'opening_rate']
o_r
Out[ ]:
Grupo opening_rate
0 CONTROLE 0.867925
1 TESTE 0.911111
In [ ]:
# Assuming o_r is a DataFrame with a 'Grupo' column
merged_df = cr.merge(o_r, on='Grupo')
merged_df['conversion_rate'] = ((merged_df['conversion_rate'] * 100).round(2)).astype(str) + '%'
merged_df['opening_rate'] = ((merged_df['opening_rate'] * 100).round(2)).astype(str) + '%'

print(merged_df)
      Grupo conversion_rate opening_rate
0  CONTROLE          58.49%       86.79%
1     TESTE          73.33%       91.11%
In [ ]:
merged_df
Out[ ]:
Grupo conversion_rate opening_rate
0 CONTROLE 58.49% 86.79%
1 TESTE 73.33% 91.11%
In [ ]:
import statsmodels.api as sm
from scipy import stats

# Criando a tabela de contingência
tabela_contingencia = pd.crosstab(df_merged['Grupo'], df_merged['Comprou'])

# Realizando o teste
chi2, p, df, expected = stats.chi2_contingency(tabela_contingencia)

# Imprimindo os resultados
print("Valor de p:", p)

# Se p < 0.05, há significância estatística
if p < 0.05:
    print("Existe relação significativa entre Grupo e Comprou")
else:
    print("Não há relação significativa entre Grupo e Comprou")
Valor de p: 0.1850463335809991
Não há relação significativa entre Grupo e Comprou
In [ ]:
from scipy.stats import chi2_contingency

# Filter the dataframe for 'CONTROLE' and 'TESTE' groups
df_controle = df_merged[df_merged['Grupo'] == 'CONTROLE']
df_teste = df_merged[df_merged['Grupo'] == 'TESTE']

# Create contingency tables
contingency_table_controle = pd.crosstab(df_controle['Grupo'], df_controle['Comprou'])
contingency_table_teste = pd.crosstab(df_teste['Grupo'], df_teste['Comprou'])

# Perform Chi-Square test for 'CONTROLE' group
chi2_controle, p_controle, dof_controle, expected_controle = chi2_contingency(contingency_table_controle)

# Perform Chi-Square test for 'TESTE' group
chi2_teste, p_teste, dof_teste, expected_teste = chi2_contingency(contingency_table_teste)

#print(f"Chi-square statistic for 'CONTROLE' group: {chi2_controle}")
print(f"P-value for 'CONTROLE' group: {p_controle}")

# print(f"Chi-square statistic for 'TESTE' group: {chi2_teste}")
print(f"P-value for 'TESTE' group: {p_teste}")
P-value for 'CONTROLE' group: 1.0
P-value for 'TESTE' group: 1.0
In [ ]:
from scipy.stats import fisher_exact

# Create contingency table
contingency_table = pd.crosstab(df_merged['Grupo'], df_merged['Comprou'])

# Perform Fisher's Exact Test
odds_ratio, p_value = fisher_exact(contingency_table)

# print(f"Odds Ratio: {odds_ratio}")
print(f"P-value: {p_value}")


# Se p < 0.05, há significância estatística
if p < 0.05:
    print("Existe relação significativa entre Grupo e Comprou")
else:
    print("Não há relação significativa entre Grupo e Comprou")
P-value: 0.1409815141818997
Não há relação significativa entre Grupo e Comprou